1- #![ feature( test) ]
2-
3- extern crate pico_sys as pico;
1+ extern crate criterion;
42extern crate httparse;
53
6- extern crate test;
4+ use std:: time:: Duration ;
5+
6+ use criterion:: { black_box, criterion_group, criterion_main, Criterion , Throughput } ;
77
88const REQ_SHORT : & ' static [ u8 ] = b"\
99 GET / HTTP/1.0\r \n \
@@ -22,101 +22,72 @@ Keep-Alive: 115\r\n\
2222 Connection: keep-alive\r \n \
2323 Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; __utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; __utmz=xxxxxxxxx.xxxxxxxxxx.x.x.utmccn=(referral)|utmcsr=reader.livedoor.com|utmcct=/reader/|utmcmd=referral|padding=under256\r \n \r \n ";
2424
25+ fn req ( c : & mut Criterion ) {
26+ let mut headers = [ httparse:: Header { name : "" , value : & [ ] } ; 16 ] ;
27+ let mut req = httparse:: Request :: new ( & mut headers) ;
2528
26- #[ bench]
27- fn bench_pico ( b : & mut test:: Bencher ) {
28- use std:: mem;
29-
30- #[ repr( C ) ]
31- #[ derive( Clone , Copy ) ]
32- struct Header < ' a > ( & ' a [ u8 ] , & ' a [ u8 ] ) ;
33-
34-
35- #[ repr( C ) ]
36- struct Headers < ' a > ( & ' a mut [ Header < ' a > ] ) ;
37- let method = [ 0i8 ; 16 ] ;
38- let path = [ 0i8 ; 16 ] ;
39- let mut minor_version = 0 ;
40- let mut h = [ Header ( & [ ] , & [ ] ) ; 16 ] ;
41- let mut h_len = h. len ( ) ;
42- let headers = Headers ( & mut h) ;
43- let prev_buf_len = 0 ;
44-
45- b. iter ( || {
46- let ret = unsafe {
47- pico:: ffi:: phr_parse_request (
48- REQ . as_ptr ( ) as * const _ ,
49- REQ . len ( ) ,
50- & mut method. as_ptr ( ) ,
51- & mut 16 ,
52- & mut path. as_ptr ( ) ,
53- & mut 16 ,
54- & mut minor_version,
55- mem:: transmute :: < * mut Header , * mut pico:: ffi:: phr_header > ( headers. 0 . as_mut_ptr ( ) ) ,
56- & mut h_len as * mut usize as * mut _ ,
57- prev_buf_len
58- )
59- } ;
60- assert_eq ! ( ret, REQ . len( ) as i32 ) ;
61- } ) ;
62- b. bytes = REQ . len ( ) as u64 ;
29+ c. benchmark_group ( "req" )
30+ . throughput ( Throughput :: Bytes ( REQ . len ( ) as u64 ) )
31+ . bench_function ( "req" , |b| b. iter ( || {
32+ assert_eq ! ( black_box( req. parse( REQ ) . unwrap( ) ) , httparse:: Status :: Complete ( REQ . len( ) ) ) ;
33+ } ) ) ;
6334}
6435
65- #[ bench]
66- fn bench_httparse ( b : & mut test:: Bencher ) {
36+ fn req_short ( c : & mut Criterion ) {
6737 let mut headers = [ httparse:: Header { name : "" , value : & [ ] } ; 16 ] ;
6838 let mut req = httparse:: Request :: new ( & mut headers) ;
69- b. iter ( || {
70- assert_eq ! ( req. parse( REQ ) . unwrap( ) , httparse:: Status :: Complete ( REQ . len( ) ) ) ;
71- } ) ;
72- b. bytes = REQ . len ( ) as u64 ;
73- }
7439
75- #[ bench]
76- fn bench_pico_short ( b : & mut test:: Bencher ) {
77- use std:: mem;
40+ c. benchmark_group ( "req_short" )
41+ . throughput ( Throughput :: Bytes ( REQ_SHORT . len ( ) as u64 ) )
42+ . bench_function ( "req_short" , |b| b. iter ( || {
43+ assert_eq ! ( black_box( req. parse( REQ_SHORT ) . unwrap( ) ) , httparse:: Status :: Complete ( REQ_SHORT . len( ) ) ) ;
44+ } ) ) ;
45+ }
7846
79- #[ repr( C ) ]
80- #[ derive( Clone , Copy ) ]
81- struct Header < ' a > ( & ' a [ u8 ] , & ' a [ u8 ] ) ;
47+ const RESP_SHORT : & ' static [ u8 ] = b"\
48+ HTTP/1.0 200 OK\r \n \
49+ Date: Wed, 21 Oct 2015 07:28:00 GMT\r \n \
50+ Set-Cookie: session=60; user_id=1\r \n \r \n ";
8251
52+ // These particular headers don't all make semantic sense for a response, but they're syntactically valid.
53+ const RESP : & ' static [ u8 ] = b"\
54+ HTTP/1.1 200 OK\r \n \
55+ Date: Wed, 21 Oct 2015 07:28:00 GMT\r \n \
56+ Host: www.kittyhell.com\r \n \
57+ User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 Pathtraq/0.9\r \n \
58+ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r \n \
59+ Accept-Language: ja,en-us;q=0.7,en;q=0.3\r \n \
60+ Accept-Encoding: gzip,deflate\r \n \
61+ Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r \n \
62+ Keep-Alive: 115\r \n \
63+ Connection: keep-alive\r \n \
64+ Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; __utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; __utmz=xxxxxxxxx.xxxxxxxxxx.x.x.utmccn=(referral)|utmcsr=reader.livedoor.com|utmcct=/reader/|utmcmd=referral|padding=under256\r \n \r \n ";
8365
84- #[ repr( C ) ]
85- struct Headers < ' a > ( & ' a mut [ Header < ' a > ] ) ;
86- let method = [ 0i8 ; 16 ] ;
87- let path = [ 0i8 ; 16 ] ;
88- let mut minor_version = 0 ;
89- let mut h = [ Header ( & [ ] , & [ ] ) ; 16 ] ;
90- let mut h_len = h. len ( ) ;
91- let headers = Headers ( & mut h) ;
92- let prev_buf_len = 0 ;
66+ fn resp ( c : & mut Criterion ) {
67+ let mut headers = [ httparse:: Header { name : "" , value : & [ ] } ; 16 ] ;
68+ let mut resp = httparse:: Response :: new ( & mut headers) ;
9369
94- b. iter ( || {
95- let ret = unsafe {
96- pico:: ffi:: phr_parse_request (
97- REQ_SHORT . as_ptr ( ) as * const _ ,
98- REQ_SHORT . len ( ) ,
99- & mut method. as_ptr ( ) ,
100- & mut 16 ,
101- & mut path. as_ptr ( ) ,
102- & mut 16 ,
103- & mut minor_version,
104- mem:: transmute :: < * mut Header , * mut pico:: ffi:: phr_header > ( headers. 0 . as_mut_ptr ( ) ) ,
105- & mut h_len as * mut usize as * mut _ ,
106- prev_buf_len
107- )
108- } ;
109- assert_eq ! ( ret, REQ_SHORT . len( ) as i32 ) ;
110- } ) ;
111- b. bytes = REQ_SHORT . len ( ) as u64 ;
70+ c. benchmark_group ( "resp" )
71+ . throughput ( Throughput :: Bytes ( RESP . len ( ) as u64 ) )
72+ . bench_function ( "resp" , |b| b. iter ( || {
73+ assert_eq ! ( black_box( resp. parse( RESP ) . unwrap( ) ) , httparse:: Status :: Complete ( RESP . len( ) ) ) ;
74+ } ) ) ;
11275}
11376
114- #[ bench]
115- fn bench_httparse_short ( b : & mut test:: Bencher ) {
77+ fn resp_short ( c : & mut Criterion ) {
11678 let mut headers = [ httparse:: Header { name : "" , value : & [ ] } ; 16 ] ;
117- let mut req = httparse:: Request :: new ( & mut headers) ;
118- b. iter ( || {
119- assert_eq ! ( req. parse( REQ_SHORT ) . unwrap( ) , httparse:: Status :: Complete ( REQ_SHORT . len( ) ) ) ;
120- } ) ;
121- b. bytes = REQ_SHORT . len ( ) as u64 ;
79+ let mut resp = httparse:: Response :: new ( & mut headers) ;
80+
81+ c. benchmark_group ( "resp_short" )
82+ . throughput ( Throughput :: Bytes ( RESP_SHORT . len ( ) as u64 ) )
83+ . bench_function ( "resp_short" , |b| b. iter ( || {
84+ assert_eq ! ( black_box( resp. parse( RESP_SHORT ) . unwrap( ) ) , httparse:: Status :: Complete ( RESP_SHORT . len( ) ) ) ;
85+ } ) ) ;
86+ }
87+
88+ criterion_group ! {
89+ name = benches;
90+ config = Criterion :: default ( ) . sample_size( 100 ) . measurement_time( Duration :: from_secs( 10 ) ) ;
91+ targets = req, req_short, resp, resp_short
12292}
93+ criterion_main ! ( benches) ;
0 commit comments