Skip to content

Commit 91f74b4

Browse files
committed
add missing benchmarks in httparse and pichohttpparser
1 parent a895260 commit 91f74b4

File tree

3 files changed

+75
-29
lines changed

3 files changed

+75
-29
lines changed

http/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ The benchmarks were run on a late 2013 Macbook Pro, quad core 2,3 GHz Intel Core
1818
| http-parser | 606 ns/iter (+/- 367 ns) | 56,385 ns/iter (+/- 148 ns) | 266254 ns/iter (+/- 37071 ns) | 1137 ns/iter (+/- 18 ns) |
1919
| attoparsec | | 241.5 μs/iter (+/-5.7 μs) | 1.836 ms/iter (+/- 137 μs) | |
2020
| combine | 1,394 ns/iter (+/- 489) = 208 MB/s | 89,875 ns/iter (+/- 12,575) = 237 MB/s | 453,297 ns/iter (+/- 260,973) = 235 MB/s | 2,076 ns/iter (+/- 436) = 338 MB/s |
21-
| httparse | 213 ns/iter (+/- 39) = 1366 MB/s | | | 472 ns/iter (+/- 162) = 1489 MB/s |
21+
| httparse | 213 ns/iter (+/- 39) = 1366 MB/s | 15,432 ns/iter (+/- 1,564) = 1385 MB/s | 78,121 ns/iter (+/- 12,476) = 1368 MB/s | 472 ns/iter (+/- 162) = 1489 MB/s |
2222
| nom | 889 ns/iter (+/- 411) = 327 MB/s | 59,918 ns/iter (+/- 5,372) = 356 MB/s | 333,344 ns/iter (+/- 49,823) = 320 MB/s | 1,544 ns/iter (+/- 294) = 455 MB/s |
2323
| nom (optimized) | 183 ns/iter (+/- 25) = 1590 MB/s | **12,253 ns/iter (+/- 2,473) = 1744 MB/s** | **61,519 ns/iter (+/- 14,660) = 1737 MB/s** | **308 ns/iter (+/- 48) = 2282 MB/s** |
24-
| picohttpparser | **170 ns/iter (+/- 29) = 1711 MB/s** | | | 350 ns/iter (+/- 76) = 2008 MB/s |
24+
| picohttpparser | **170 ns/iter (+/- 29) = 1711 MB/s** | 13,260 ns/iter (+/- 1,786) = 1612 MB/s | 65,415 ns/iter (+/- 5,058) = 1634 MB/s | 350 ns/iter (+/- 76) = 2008 MB/s |
2525

2626
(the "nom-optimized" version is an experiment to match httparse and picohttparser APIs, and bring
2727
in SIMD based parsing in nom)

http/httparse/src/main.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,35 @@ Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; __utma=xxxxxx
5050
parse(b, data)
5151
}
5252

53+
fn small_test(b: &mut Bencher) {
54+
let data = include_bytes!("../../http-requests.txt");
55+
b.bytes = data.len() as u64;
56+
parse(b, data)
57+
}
58+
59+
fn bigger_test(b: &mut Bencher) {
60+
let data = include_bytes!("../../bigger.txt");
61+
b.bytes = data.len() as u64;
62+
parse(b, data)
63+
}
5364

5465
fn parse(b: &mut Bencher, buffer: &[u8]) {
55-
let mut headers = [httparse::Header{ name: "", value: &[] }; 16];
56-
let mut req = httparse::Request::new(&mut headers);
5766
b.iter(|| {
5867
let mut buf = black_box(buffer);
59-
assert_eq!(req.parse(buf).unwrap(), httparse::Status::Complete(buf.len()));
68+
let mut index = 0;
69+
let len = buf.len();
70+
while index < len {
71+
let slice = &buf[index..];
72+
73+
let mut headers = [httparse::Header{ name: "", value: &[] }; 16];
74+
let mut req = httparse::Request::new(&mut headers);
75+
76+
if let httparse::Status::Complete(sz) = req.parse(buf).unwrap() {
77+
index += sz;
78+
} else {
79+
panic!("parse error");
80+
}
81+
}
6082
});
6183

6284
/*
@@ -81,5 +103,5 @@ fn parse(b: &mut Bencher, buffer: &[u8]) {
81103
*/
82104
}
83105

84-
benchmark_group!(http, one_test, httparse_example_test);
106+
benchmark_group!(http, one_test, small_test, bigger_test, httparse_example_test);
85107
benchmark_main!(http);

http/picohttpparser/src/main.rs

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; __utma=xxxxxx
5050
parse(b, data)
5151
}
5252

53+
fn small_test(b: &mut Bencher) {
54+
let data = include_bytes!("../../http-requests.txt");
55+
b.bytes = data.len() as u64;
56+
parse(b, data)
57+
}
58+
59+
fn bigger_test(b: &mut Bencher) {
60+
let data = include_bytes!("../../bigger.txt");
61+
b.bytes = data.len() as u64;
62+
parse(b, data)
63+
}
5364

5465
fn parse(b: &mut Bencher, buffer: &[u8]) {
5566
use std::mem;
@@ -60,34 +71,47 @@ fn parse(b: &mut Bencher, buffer: &[u8]) {
6071

6172
#[repr(C)]
6273
struct Headers<'a>(&'a mut [Header<'a>]);
63-
let method = [0i8; 16];
64-
let path = [0i8; 100];
65-
let mut minor_version = 0;
66-
let mut h = [Header(&[], &[]); 16];
67-
let mut h_len = h.len();
68-
let headers = Headers(&mut h);
69-
let prev_buf_len = 0;
7074

7175
b.bytes = buffer.len() as u64;
7276
b.iter(|| {
7377
let mut buf = black_box(buffer);
74-
let ret = unsafe {
75-
pico::ffi::phr_parse_request(
76-
buf.as_ptr() as *const _,
77-
buf.len(),
78-
&mut method.as_ptr(),
79-
&mut 16,
80-
&mut path.as_ptr(),
81-
&mut 100,
82-
&mut minor_version,
83-
mem::transmute::<*mut Header, *mut pico::ffi::phr_header>(headers.0.as_mut_ptr()),
84-
&mut h_len as *mut usize as *mut _,
85-
prev_buf_len
86-
)
87-
};
88-
assert_eq!(ret, buf.len() as i32);
78+
let mut index = 0;
79+
let len = buf.len();
80+
while index < len {
81+
let slice = &buf[index..];
82+
83+
let method = [0i8; 16];
84+
let path = [0i8; 100];
85+
let mut minor_version = 0;
86+
let mut h = [Header(&[], &[]); 16];
87+
let mut h_len = h.len();
88+
let headers = Headers(&mut h);
89+
let prev_buf_len = 0;
90+
91+
let ret = unsafe {
92+
pico::ffi::phr_parse_request(
93+
slice.as_ptr() as *const _,
94+
slice.len(),
95+
&mut method.as_ptr(),
96+
&mut 16,
97+
&mut path.as_ptr(),
98+
&mut 100,
99+
&mut minor_version,
100+
mem::transmute::<*mut Header, *mut pico::ffi::phr_header>(headers.0.as_mut_ptr()),
101+
&mut h_len as *mut usize as *mut _,
102+
prev_buf_len
103+
)
104+
};
105+
106+
if ret < 0 {
107+
println!("error: ret = {}", ret);
108+
break;
109+
}
110+
111+
index += ret as usize;
112+
}
89113
});
90114
}
91115

92-
benchmark_group!(http, one_test, httparse_example_test);
116+
benchmark_group!(http, one_test, small_test, bigger_test, httparse_example_test);
93117
benchmark_main!(http);

0 commit comments

Comments
 (0)