1 macro_rules! bench {
2     ($name:ident($map:ident, $b:ident) $body:expr) => {
3         mod $name {
4             #[allow(unused_imports)]
5             use super::custom_hdr;
6             use fnv::FnvHasher;
7             use http::header::*;
8             use seahash::SeaHasher;
9             use std::hash::BuildHasherDefault;
10             #[allow(unused_imports)]
11             use test::{self, Bencher};
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 crate::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 bench!(set_10_get_1_custom_med(new_map, b) {
212     let hdrs = super::med_custom_hdr(10);
213 
214     b.iter(|| {
215         let mut h = new_map();
216 
217         for hdr in &hdrs {
218             h.insert(hdr.clone(), "foo");
219         }
220 
221         test::black_box(h.get(&hdrs[0]));
222     })
223 });
224 
225 bench!(set_10_get_1_custom_long(new_map, b) {
226     let hdrs = super::long_custom_hdr(10);
227 
228     b.iter(|| {
229         let mut h = new_map();
230 
231         for hdr in &hdrs {
232             h.insert(hdr.clone(), "foo");
233         }
234 
235         test::black_box(h.get(&hdrs[0]));
236     })
237 });
238 
239 bench!(set_10_get_1_custom_very_long(new_map, b) {
240     let hdrs = super::very_long_custom_hdr(10);
241 
242     b.iter(|| {
243         let mut h = new_map();
244 
245         for hdr in &hdrs {
246             h.insert(hdr.clone(), "foo");
247         }
248 
249         test::black_box(h.get(&hdrs[0]));
250     })
251 });
252 
253 bench!(set_20_get_1_custom_short(new_map, b) {
254     let hdrs = custom_hdr(20);
255 
256     b.iter(|| {
257         let mut h = new_map();
258 
259         for hdr in &hdrs {
260             h.insert(hdr.clone(), "foo");
261         }
262 
263         test::black_box(h.get(&hdrs[0]));
264     })
265 });
266 
267 bench!(set_20_get_1_custom_med(new_map, b) {
268     let hdrs = super::med_custom_hdr(20);
269 
270     b.iter(|| {
271         let mut h = new_map();
272 
273         for hdr in &hdrs {
274             h.insert(hdr.clone(), "foo");
275         }
276 
277         test::black_box(h.get(&hdrs[0]));
278     })
279 });
280 
281 bench!(set_20_get_1_custom_long(new_map, b) {
282     let hdrs = super::long_custom_hdr(20);
283 
284     b.iter(|| {
285         let mut h = new_map();
286 
287         for hdr in &hdrs {
288             h.insert(hdr.clone(), "foo");
289         }
290 
291         test::black_box(h.get(&hdrs[0]));
292     })
293 });
294 
295 bench!(set_20_get_1_custom_very_long(new_map, b) {
296     let hdrs = super::very_long_custom_hdr(20);
297 
298     b.iter(|| {
299         let mut h = new_map();
300 
301         for hdr in &hdrs {
302             h.insert(hdr.clone(), "foo");
303         }
304 
305         test::black_box(h.get(&hdrs[0]));
306     })
307 });
308 
309 bench!(insert_all_std_headers(new_map, b) {
310     b.iter(|| {
311         let mut h = new_map();
312 
313         for hdr in super::STD {
314             test::black_box(h.insert(hdr.clone(), "foo"));
315         }
316     })
317 });
318 
319 bench!(insert_79_custom_std_headers(new_map, b) {
320     let hdrs = super::custom_std(79);
321 
322     b.iter(|| {
323         let mut h = new_map();
324 
325         for hdr in &hdrs {
326             h.insert(hdr.clone(), "foo");
327         }
328     })
329 });
330 
331 bench!(insert_100_custom_headers(new_map, b) {
332     let hdrs = custom_hdr(100);
333 
334     b.iter(|| {
335         let mut h = new_map();
336 
337         for hdr in &hdrs {
338             test::black_box(h.insert(hdr.clone(), "foo"));
339         }
340     })
341 });
342 
343 bench!(insert_500_custom_headers(new_map, b) {
344     let hdrs = custom_hdr(500);
345 
346     b.iter(|| {
347         let mut h = new_map();
348 
349         for hdr in &hdrs {
350             test::black_box(h.insert(hdr.clone(), "foo"));
351         }
352     })
353 });
354 
355 bench!(insert_one_15_char_header(new_map, b) {
356     let hdr: HeaderName = "abcd-abcd-abcde"
357         .parse().unwrap();
358 
359     b.iter(|| {
360         let mut h = new_map();
361         h.insert(hdr.clone(), "hello");
362         test::black_box(h);
363     })
364 });
365 
366 bench!(insert_one_25_char_header(new_map, b) {
367     let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcde"
368         .parse().unwrap();
369 
370     b.iter(|| {
371         let mut h = new_map();
372         h.insert(hdr.clone(), "hello");
373         test::black_box(h);
374     })
375 });
376 
377 bench!(insert_one_50_char_header(new_map, b) {
378     let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcde"
379         .parse().unwrap();
380 
381     b.iter(|| {
382         let mut h = new_map();
383         h.insert(hdr.clone(), "hello");
384         test::black_box(h);
385     })
386 });
387 
388 bench!(insert_one_100_char_header(new_map, b) {
389     let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcdeabcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcde"
390         .parse().unwrap();
391 
392     b.iter(|| {
393         let mut h = new_map();
394         h.insert(hdr.clone(), "hello");
395         test::black_box(h);
396     })
397 });
398 
399 const HN_HDRS: [(&'static str, &'static str); 11] = [
400     ("Date", "Fri, 27 Jan 2017 23:00:00 GMT"),
401     ("Content-Type", "text/html; charset=utf-8"),
402     ("Transfer-Encoding", "chunked"),
403     ("Connection", "keep-alive"),
404     ("Set-Cookie", "__cfduid=dbdfbbe3822b61cb8750ba37d894022151485558000; expires=Sat, 27-Jan-18 23:00:00 GMT; path=/; domain=.ycombinator.com; HttpOnly"),
405     ("Vary", "Accept-Encoding"),
406     ("Cache-Control", "private"),
407     ("X-Frame-Options", "DENY"),
408     ("Strict-Transport-Security", "max-age=31556900; includeSubDomains"),
409     ("Server", "cloudflare-nginx"),
410     ("CF-RAY", "327fd1809f3c1baf-SEA"),
411 ];
412 
413 bench!(hn_hdrs_set_8_get_many(new_map, b) {
414     let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS[..8].iter()
415         .map(|&(name, val)| (name.parse().unwrap(), val))
416         .collect();
417 
418     b.iter(|| {
419         let mut h = new_map();
420 
421         for &(ref name, val) in hdrs.iter() {
422             h.insert(name.clone(), val);
423         }
424 
425         for _ in 0..15 {
426             test::black_box(h.get(&CONTENT_LENGTH));
427             test::black_box(h.get(&VARY));
428         }
429     });
430 });
431 
432 bench!(hn_hdrs_set_8_get_miss(new_map, b) {
433     let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS[..8].iter()
434         .map(|&(name, val)| (name.parse().unwrap(), val))
435         .collect();
436 
437     let miss: HeaderName = "x-wat".parse().unwrap();
438 
439     b.iter(|| {
440         let mut h = new_map();
441 
442         for &(ref name, val) in hdrs.iter() {
443             h.insert(name.clone(), val);
444         }
445 
446         test::black_box(h.get(&CONTENT_LENGTH));
447         test::black_box(h.get(&miss));
448     });
449 });
450 
451 bench!(hn_hdrs_set_11_get_with_miss(new_map, b) {
452     let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS.iter()
453         .map(|&(name, val)| (name.parse().unwrap(), val))
454         .collect();
455 
456     let miss: HeaderName = "x-wat".parse().unwrap();
457 
458     b.iter(|| {
459         let mut h = new_map();
460 
461         for &(ref name, val) in hdrs.iter() {
462             h.insert(name.clone(), val);
463         }
464 
465         for _ in 0..10 {
466             test::black_box(h.get(&CONTENT_LENGTH));
467             test::black_box(h.get(&VARY));
468             test::black_box(h.get(&miss));
469         }
470     });
471 });
472 
473 use http::header::*;
474 
custom_hdr(n: usize) -> Vec<HeaderName>475 fn custom_hdr(n: usize) -> Vec<HeaderName> {
476     (0..n)
477         .map(|i| {
478             let s = format!("x-custom-{}", i);
479             s.parse().unwrap()
480         })
481         .collect()
482 }
483 
med_custom_hdr(n: usize) -> Vec<HeaderName>484 fn med_custom_hdr(n: usize) -> Vec<HeaderName> {
485     (0..n)
486         .map(|i| {
487             let s = format!("content-length-{}", i);
488             s.parse().unwrap()
489         })
490         .collect()
491 }
492 
long_custom_hdr(n: usize) -> Vec<HeaderName>493 fn long_custom_hdr(n: usize) -> Vec<HeaderName> {
494     (0..n)
495         .map(|i| {
496             let s = format!("access-control-allow-headers-{}", i);
497             s.parse().unwrap()
498         })
499         .collect()
500 }
501 
very_long_custom_hdr(n: usize) -> Vec<HeaderName>502 fn very_long_custom_hdr(n: usize) -> Vec<HeaderName> {
503     (0..n)
504         .map(|i| {
505             let s = format!("access-control-allow-access-control-allow-headers-{}", i);
506             s.parse().unwrap()
507         })
508         .collect()
509 }
510 
custom_std(n: usize) -> Vec<HeaderName>511 fn custom_std(n: usize) -> Vec<HeaderName> {
512     (0..n)
513         .map(|i| {
514             let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
515             s.parse().unwrap()
516         })
517         .collect()
518 }
519 
520 const STD: &'static [HeaderName] = &[
521     ACCEPT,
522     ACCEPT_CHARSET,
523     ACCEPT_ENCODING,
524     ACCEPT_LANGUAGE,
525     ACCEPT_RANGES,
526     ACCESS_CONTROL_ALLOW_CREDENTIALS,
527     ACCESS_CONTROL_ALLOW_HEADERS,
528     ACCESS_CONTROL_ALLOW_METHODS,
529     ACCESS_CONTROL_ALLOW_ORIGIN,
530     ACCESS_CONTROL_EXPOSE_HEADERS,
531     ACCESS_CONTROL_MAX_AGE,
532     ACCESS_CONTROL_REQUEST_HEADERS,
533     ACCESS_CONTROL_REQUEST_METHOD,
534     AGE,
535     ALLOW,
536     ALT_SVC,
537     AUTHORIZATION,
538     CACHE_CONTROL,
539     CONNECTION,
540     CONTENT_DISPOSITION,
541     CONTENT_ENCODING,
542     CONTENT_LANGUAGE,
543     CONTENT_LENGTH,
544     CONTENT_LOCATION,
545     CONTENT_RANGE,
546     CONTENT_SECURITY_POLICY,
547     CONTENT_SECURITY_POLICY_REPORT_ONLY,
548     CONTENT_TYPE,
549     COOKIE,
550     DNT,
551     DATE,
552     ETAG,
553     EXPECT,
554     EXPIRES,
555     FORWARDED,
556     FROM,
557     HOST,
558     IF_MATCH,
559     IF_MODIFIED_SINCE,
560     IF_NONE_MATCH,
561     IF_RANGE,
562     IF_UNMODIFIED_SINCE,
563     LAST_MODIFIED,
564     LINK,
565     LOCATION,
566     MAX_FORWARDS,
567     ORIGIN,
568     PRAGMA,
569     PROXY_AUTHENTICATE,
570     PROXY_AUTHORIZATION,
571     PUBLIC_KEY_PINS,
572     PUBLIC_KEY_PINS_REPORT_ONLY,
573     RANGE,
574     REFERER,
575     REFERRER_POLICY,
576     REFRESH,
577     RETRY_AFTER,
578     SERVER,
579     SET_COOKIE,
580     STRICT_TRANSPORT_SECURITY,
581     TE,
582     TRAILER,
583     TRANSFER_ENCODING,
584     USER_AGENT,
585     UPGRADE,
586     UPGRADE_INSECURE_REQUESTS,
587     VARY,
588     VIA,
589     WARNING,
590     WWW_AUTHENTICATE,
591     X_CONTENT_TYPE_OPTIONS,
592     X_DNS_PREFETCH_CONTROL,
593     X_FRAME_OPTIONS,
594     X_XSS_PROTECTION,
595 ];
596