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