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