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 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 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 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 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 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