1 macro_rules! bench {
2 ($name:ident($map:ident, $b:ident) $body:expr) => {
3 mod $name {
4 #[allow(unused_imports)]
5 use test::{self, Bencher};
6 use seahash::SeaHasher;
7 use fnv::FnvHasher;
8 use std::hash::BuildHasherDefault;
9 use http::header::*;
10 #[allow(unused_imports)]
11 use super::custom_hdr;
12
13 #[bench]
14 fn header_map($b: &mut Bencher) {
15 let $map = || HeaderMap::default();
16 $body
17 }
18
19 #[bench]
20 fn order_map_fnv($b: &mut Bencher) {
21 use indexmap::IndexMap;
22 let $map = || IndexMap::<_, _, BuildHasherDefault<FnvHasher>>::default();
23 $body
24 }
25
26 #[bench]
27 fn vec_map($b: &mut Bencher) {
28 use vec_map::VecMap;
29
30 let $map = || VecMap::with_capacity(0);
31 $body
32 }
33
34 #[bench]
35 fn order_map_seahash($b: &mut Bencher) {
36 use indexmap::IndexMap;
37 let $map = || IndexMap::<_, _, BuildHasherDefault<SeaHasher>>::default();
38 $body
39 }
40
41 /*
42 #[bench]
43 fn order_map_siphash($b: &mut Bencher) {
44 use indexmap::IndexMap;
45 let $map = || IndexMap::new();
46 $body
47 }
48
49 #[bench]
50 fn std_map_siphash($b: &mut Bencher) {
51 use std::collections::HashMap;
52 let $map = || HashMap::new();
53 $body
54 }
55 */
56 }
57 };
58 }
59
60 bench!(new_insert_get_host(new_map, b) {
61 b.iter(|| {
62 let mut h = new_map();
63 h.insert(HOST, "hyper.rs");
64 test::black_box(h.get(&HOST));
65 })
66 });
67
68 bench!(insert_4_std_get_30(new_map, b) {
69
70 b.iter(|| {
71 let mut h = new_map();
72
73 for i in 0..4 {
74 h.insert(super::STD[i].clone(), "foo");
75 }
76
77 for i in 0..30 {
78 test::black_box(h.get(&super::STD[i % 4]));
79 }
80 })
81 });
82
83 bench!(insert_6_std_get_6(new_map, b) {
84
85 b.iter(|| {
86 let mut h = new_map();
87
88 for i in 0..6 {
89 h.insert(super::STD[i].clone(), "foo");
90 }
91
92 for i in 0..6 {
93 test::black_box(h.get(&super::STD[i % 4]));
94 }
95 })
96 });
97
98 /*
99 bench!(insert_remove_host(new_map, b) {
100 let mut h = new_map();
101
102 b.iter(|| {
103 test::black_box(h.insert(HOST, "hyper.rs"));
104 test::black_box(h.remove(&HOST));
105 })
106 });
107
108 bench!(insert_insert_host(new_map, b) {
109 let mut h = new_map();
110
111 b.iter(|| {
112 test::black_box(h.insert(HOST, "hyper.rs"));
113 test::black_box(h.insert(HOST, "hyper.rs"));
114 })
115 });
116 */
117
118 bench!(get_10_of_20_std(new_map, b) {
119 let mut h = new_map();
120
121 for hdr in super::STD[10..30].iter() {
122 h.insert(hdr.clone(), hdr.as_str().to_string());
123 }
124
125 b.iter(|| {
126 for hdr in &super::STD[10..20] {
127 test::black_box(h.get(hdr));
128 }
129 })
130 });
131
132 bench!(get_100_std(new_map, b) {
133 let mut h = new_map();
134
135 for hdr in super::STD.iter() {
136 h.insert(hdr.clone(), hdr.as_str().to_string());
137 }
138
139 b.iter(|| {
140 for i in 0..100 {
141 test::black_box(h.get(&super::STD[i % super::STD.len()]));
142 }
143 })
144 });
145
146 bench!(set_8_get_1_std(new_map, b) {
147 b.iter(|| {
148 let mut h = new_map();
149
150 for hdr in &super::STD[0..8] {
151 h.insert(hdr.clone(), "foo");
152 }
153
154 test::black_box(h.get(&super::STD[0]));
155 })
156 });
157
158 bench!(set_10_get_1_std(new_map, b) {
159 b.iter(|| {
160 let mut h = new_map();
161
162 for hdr in &super::STD[0..10] {
163 h.insert(hdr.clone(), "foo");
164 }
165
166 test::black_box(h.get(&super::STD[0]));
167 })
168 });
169
170 bench!(set_20_get_1_std(new_map, b) {
171 b.iter(|| {
172 let mut h = new_map();
173
174 for hdr in &super::STD[0..20] {
175 h.insert(hdr.clone(), "foo");
176 }
177
178 test::black_box(h.get(&super::STD[0]));
179 })
180 });
181
182 bench!(get_10_custom_short(new_map, b) {
183 let hdrs = custom_hdr(20);
184 let mut h = new_map();
185
186 for hdr in &hdrs {
187 h.insert(hdr.clone(), hdr.as_str().to_string());
188 }
189
190 b.iter(|| {
191 for hdr in &hdrs[..10] {
192 test::black_box(h.get(hdr));
193 }
194 })
195 });
196
197 bench!(set_10_get_1_custom_short(new_map, b) {
198 let hdrs = custom_hdr(10);
199
200 b.iter(|| {
201 let mut h = new_map();
202
203 for hdr in &hdrs {
204 h.insert(hdr.clone(), "foo");
205 }
206
207 test::black_box(h.get(&hdrs[0]));
208 })
209 });
210
211
212 bench!(set_10_get_1_custom_med(new_map, b) {
213 let hdrs = super::med_custom_hdr(10);
214
215 b.iter(|| {
216 let mut h = new_map();
217
218 for hdr in &hdrs {
219 h.insert(hdr.clone(), "foo");
220 }
221
222 test::black_box(h.get(&hdrs[0]));
223 })
224 });
225
226 bench!(set_10_get_1_custom_long(new_map, b) {
227 let hdrs = super::long_custom_hdr(10);
228
229 b.iter(|| {
230 let mut h = new_map();
231
232 for hdr in &hdrs {
233 h.insert(hdr.clone(), "foo");
234 }
235
236 test::black_box(h.get(&hdrs[0]));
237 })
238 });
239
240 bench!(set_10_get_1_custom_very_long(new_map, b) {
241 let hdrs = super::very_long_custom_hdr(10);
242
243 b.iter(|| {
244 let mut h = new_map();
245
246 for hdr in &hdrs {
247 h.insert(hdr.clone(), "foo");
248 }
249
250 test::black_box(h.get(&hdrs[0]));
251 })
252 });
253
254 bench!(set_20_get_1_custom_short(new_map, b) {
255 let hdrs = custom_hdr(20);
256
257 b.iter(|| {
258 let mut h = new_map();
259
260 for hdr in &hdrs {
261 h.insert(hdr.clone(), "foo");
262 }
263
264 test::black_box(h.get(&hdrs[0]));
265 })
266 });
267
268 bench!(set_20_get_1_custom_med(new_map, b) {
269 let hdrs = super::med_custom_hdr(20);
270
271 b.iter(|| {
272 let mut h = new_map();
273
274 for hdr in &hdrs {
275 h.insert(hdr.clone(), "foo");
276 }
277
278 test::black_box(h.get(&hdrs[0]));
279 })
280 });
281
282 bench!(set_20_get_1_custom_long(new_map, b) {
283 let hdrs = super::long_custom_hdr(20);
284
285 b.iter(|| {
286 let mut h = new_map();
287
288 for hdr in &hdrs {
289 h.insert(hdr.clone(), "foo");
290 }
291
292 test::black_box(h.get(&hdrs[0]));
293 })
294 });
295
296 bench!(set_20_get_1_custom_very_long(new_map, b) {
297 let hdrs = super::very_long_custom_hdr(20);
298
299 b.iter(|| {
300 let mut h = new_map();
301
302 for hdr in &hdrs {
303 h.insert(hdr.clone(), "foo");
304 }
305
306 test::black_box(h.get(&hdrs[0]));
307 })
308 });
309
310 bench!(insert_all_std_headers(new_map, b) {
311 b.iter(|| {
312 let mut h = new_map();
313
314 for hdr in super::STD {
315 test::black_box(h.insert(hdr.clone(), "foo"));
316 }
317 })
318 });
319
320 bench!(insert_79_custom_std_headers(new_map, b) {
321 let hdrs = super::custom_std(79);
322
323 b.iter(|| {
324 let mut h = new_map();
325
326 for hdr in &hdrs {
327 h.insert(hdr.clone(), "foo");
328 }
329 })
330 });
331
332 bench!(insert_100_custom_headers(new_map, b) {
333 let hdrs = custom_hdr(100);
334
335 b.iter(|| {
336 let mut h = new_map();
337
338 for hdr in &hdrs {
339 test::black_box(h.insert(hdr.clone(), "foo"));
340 }
341 })
342 });
343
344 bench!(insert_500_custom_headers(new_map, b) {
345 let hdrs = custom_hdr(500);
346
347 b.iter(|| {
348 let mut h = new_map();
349
350 for hdr in &hdrs {
351 test::black_box(h.insert(hdr.clone(), "foo"));
352 }
353 })
354 });
355
356 bench!(insert_one_15_char_header(new_map, b) {
357 let hdr: HeaderName = "abcd-abcd-abcde"
358 .parse().unwrap();
359
360 b.iter(|| {
361 let mut h = new_map();
362 h.insert(hdr.clone(), "hello");
363 test::black_box(h);
364 })
365 });
366
367 bench!(insert_one_25_char_header(new_map, b) {
368 let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcde"
369 .parse().unwrap();
370
371 b.iter(|| {
372 let mut h = new_map();
373 h.insert(hdr.clone(), "hello");
374 test::black_box(h);
375 })
376 });
377
378 bench!(insert_one_50_char_header(new_map, b) {
379 let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcde"
380 .parse().unwrap();
381
382 b.iter(|| {
383 let mut h = new_map();
384 h.insert(hdr.clone(), "hello");
385 test::black_box(h);
386 })
387 });
388
389 bench!(insert_one_100_char_header(new_map, b) {
390 let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcdeabcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcde"
391 .parse().unwrap();
392
393 b.iter(|| {
394 let mut h = new_map();
395 h.insert(hdr.clone(), "hello");
396 test::black_box(h);
397 })
398 });
399
400 const HN_HDRS: [(&'static str, &'static str); 11] = [
401 ("Date", "Fri, 27 Jan 2017 23:00:00 GMT"),
402 ("Content-Type", "text/html; charset=utf-8"),
403 ("Transfer-Encoding", "chunked"),
404 ("Connection", "keep-alive"),
405 ("Set-Cookie", "__cfduid=dbdfbbe3822b61cb8750ba37d894022151485558000; expires=Sat, 27-Jan-18 23:00:00 GMT; path=/; domain=.ycombinator.com; HttpOnly"),
406 ("Vary", "Accept-Encoding"),
407 ("Cache-Control", "private"),
408 ("X-Frame-Options", "DENY"),
409 ("Strict-Transport-Security", "max-age=31556900; includeSubDomains"),
410 ("Server", "cloudflare-nginx"),
411 ("CF-RAY", "327fd1809f3c1baf-SEA"),
412 ];
413
414 bench!(hn_hdrs_set_8_get_many(new_map, b) {
415 let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS[..8].iter()
416 .map(|&(name, val)| (name.parse().unwrap(), val))
417 .collect();
418
419 b.iter(|| {
420 let mut h = new_map();
421
422 for &(ref name, val) in hdrs.iter() {
423 h.insert(name.clone(), val);
424 }
425
426 for _ in 0..15 {
427 test::black_box(h.get(&CONTENT_LENGTH));
428 test::black_box(h.get(&VARY));
429 }
430 });
431 });
432
433 bench!(hn_hdrs_set_8_get_miss(new_map, b) {
434 let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS[..8].iter()
435 .map(|&(name, val)| (name.parse().unwrap(), val))
436 .collect();
437
438 let miss: HeaderName = "x-wat".parse().unwrap();
439
440 b.iter(|| {
441 let mut h = new_map();
442
443 for &(ref name, val) in hdrs.iter() {
444 h.insert(name.clone(), val);
445 }
446
447 test::black_box(h.get(&CONTENT_LENGTH));
448 test::black_box(h.get(&miss));
449 });
450 });
451
452 bench!(hn_hdrs_set_11_get_with_miss(new_map, b) {
453 let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS.iter()
454 .map(|&(name, val)| (name.parse().unwrap(), val))
455 .collect();
456
457 let miss: HeaderName = "x-wat".parse().unwrap();
458
459 b.iter(|| {
460 let mut h = new_map();
461
462 for &(ref name, val) in hdrs.iter() {
463 h.insert(name.clone(), val);
464 }
465
466 for _ in 0..10 {
467 test::black_box(h.get(&CONTENT_LENGTH));
468 test::black_box(h.get(&VARY));
469 test::black_box(h.get(&miss));
470 }
471 });
472 });
473
474 use http::header::*;
475
custom_hdr(n: usize) -> Vec<HeaderName>476 fn custom_hdr(n: usize) -> Vec<HeaderName> {
477 (0..n).map(|i| {
478 let s = format!("x-custom-{}", i);
479 s.parse().unwrap()
480 }).collect()
481 }
482
med_custom_hdr(n: usize) -> Vec<HeaderName>483 fn med_custom_hdr(n: usize) -> Vec<HeaderName> {
484 (0..n).map(|i| {
485 let s = format!("content-length-{}", i);
486 s.parse().unwrap()
487 }).collect()
488 }
489
long_custom_hdr(n: usize) -> Vec<HeaderName>490 fn long_custom_hdr(n: usize) -> Vec<HeaderName> {
491 (0..n).map(|i| {
492 let s = format!("access-control-allow-headers-{}", i);
493 s.parse().unwrap()
494 }).collect()
495 }
496
very_long_custom_hdr(n: usize) -> Vec<HeaderName>497 fn very_long_custom_hdr(n: usize) -> Vec<HeaderName> {
498 (0..n).map(|i| {
499 let s = format!("access-control-allow-access-control-allow-headers-{}", i);
500 s.parse().unwrap()
501 }).collect()
502 }
503
custom_std(n: usize) -> Vec<HeaderName>504 fn custom_std(n: usize) -> Vec<HeaderName> {
505 (0..n).map(|i| {
506 let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
507 s.parse().unwrap()
508 }).collect()
509 }
510
511 const STD: &'static [HeaderName] = &[
512 ACCEPT,
513 ACCEPT_CHARSET,
514 ACCEPT_ENCODING,
515 ACCEPT_LANGUAGE,
516 ACCEPT_RANGES,
517 ACCESS_CONTROL_ALLOW_CREDENTIALS,
518 ACCESS_CONTROL_ALLOW_HEADERS,
519 ACCESS_CONTROL_ALLOW_METHODS,
520 ACCESS_CONTROL_ALLOW_ORIGIN,
521 ACCESS_CONTROL_EXPOSE_HEADERS,
522 ACCESS_CONTROL_MAX_AGE,
523 ACCESS_CONTROL_REQUEST_HEADERS,
524 ACCESS_CONTROL_REQUEST_METHOD,
525 AGE,
526 ALLOW,
527 ALT_SVC,
528 AUTHORIZATION,
529 CACHE_CONTROL,
530 CONNECTION,
531 CONTENT_DISPOSITION,
532 CONTENT_ENCODING,
533 CONTENT_LANGUAGE,
534 CONTENT_LENGTH,
535 CONTENT_LOCATION,
536 CONTENT_RANGE,
537 CONTENT_SECURITY_POLICY,
538 CONTENT_SECURITY_POLICY_REPORT_ONLY,
539 CONTENT_TYPE,
540 COOKIE,
541 DNT,
542 DATE,
543 ETAG,
544 EXPECT,
545 EXPIRES,
546 FORWARDED,
547 FROM,
548 HOST,
549 IF_MATCH,
550 IF_MODIFIED_SINCE,
551 IF_NONE_MATCH,
552 IF_RANGE,
553 IF_UNMODIFIED_SINCE,
554 LAST_MODIFIED,
555 LINK,
556 LOCATION,
557 MAX_FORWARDS,
558 ORIGIN,
559 PRAGMA,
560 PROXY_AUTHENTICATE,
561 PROXY_AUTHORIZATION,
562 PUBLIC_KEY_PINS,
563 PUBLIC_KEY_PINS_REPORT_ONLY,
564 RANGE,
565 REFERER,
566 REFERRER_POLICY,
567 REFRESH,
568 RETRY_AFTER,
569 SERVER,
570 SET_COOKIE,
571 STRICT_TRANSPORT_SECURITY,
572 TE,
573 TRAILER,
574 TRANSFER_ENCODING,
575 USER_AGENT,
576 UPGRADE,
577 UPGRADE_INSECURE_REQUESTS,
578 VARY,
579 VIA,
580 WARNING,
581 WWW_AUTHENTICATE,
582 X_CONTENT_TYPE_OPTIONS,
583 X_DNS_PREFETCH_CONTROL,
584 X_FRAME_OPTIONS,
585 X_XSS_PROTECTION,
586 ];
587