blob: 4ce7ed6287370e1e628dc28833560f79527907ff [file] [log] [blame]
macro_rules! bench {
($name:ident($map:ident, $b:ident) $body:expr) => {
mod $name {
#[allow(unused_imports)]
use test::{self, Bencher};
use seahash::SeaHasher;
use fnv::FnvHasher;
use std::hash::BuildHasherDefault;
use http::header::*;
#[allow(unused_imports)]
use super::custom_hdr;
#[bench]
fn header_map($b: &mut Bencher) {
let $map = || HeaderMap::default();
$body
}
#[bench]
fn order_map_fnv($b: &mut Bencher) {
use indexmap::IndexMap;
let $map = || IndexMap::<_, _, BuildHasherDefault<FnvHasher>>::default();
$body
}
#[bench]
fn vec_map($b: &mut Bencher) {
use vec_map::VecMap;
let $map = || VecMap::with_capacity(0);
$body
}
#[bench]
fn order_map_seahash($b: &mut Bencher) {
use indexmap::IndexMap;
let $map = || IndexMap::<_, _, BuildHasherDefault<SeaHasher>>::default();
$body
}
/*
#[bench]
fn order_map_siphash($b: &mut Bencher) {
use indexmap::IndexMap;
let $map = || IndexMap::new();
$body
}
#[bench]
fn std_map_siphash($b: &mut Bencher) {
use std::collections::HashMap;
let $map = || HashMap::new();
$body
}
*/
}
};
}
bench!(new_insert_get_host(new_map, b) {
b.iter(|| {
let mut h = new_map();
h.insert(HOST, "hyper.rs");
test::black_box(h.get(&HOST));
})
});
bench!(insert_4_std_get_30(new_map, b) {
b.iter(|| {
let mut h = new_map();
for i in 0..4 {
h.insert(super::STD[i].clone(), "foo");
}
for i in 0..30 {
test::black_box(h.get(&super::STD[i % 4]));
}
})
});
bench!(insert_6_std_get_6(new_map, b) {
b.iter(|| {
let mut h = new_map();
for i in 0..6 {
h.insert(super::STD[i].clone(), "foo");
}
for i in 0..6 {
test::black_box(h.get(&super::STD[i % 4]));
}
})
});
/*
bench!(insert_remove_host(new_map, b) {
let mut h = new_map();
b.iter(|| {
test::black_box(h.insert(HOST, "hyper.rs"));
test::black_box(h.remove(&HOST));
})
});
bench!(insert_insert_host(new_map, b) {
let mut h = new_map();
b.iter(|| {
test::black_box(h.insert(HOST, "hyper.rs"));
test::black_box(h.insert(HOST, "hyper.rs"));
})
});
*/
bench!(get_10_of_20_std(new_map, b) {
let mut h = new_map();
for hdr in super::STD[10..30].iter() {
h.insert(hdr.clone(), hdr.as_str().to_string());
}
b.iter(|| {
for hdr in &super::STD[10..20] {
test::black_box(h.get(hdr));
}
})
});
bench!(get_100_std(new_map, b) {
let mut h = new_map();
for hdr in super::STD.iter() {
h.insert(hdr.clone(), hdr.as_str().to_string());
}
b.iter(|| {
for i in 0..100 {
test::black_box(h.get(&super::STD[i % super::STD.len()]));
}
})
});
bench!(set_8_get_1_std(new_map, b) {
b.iter(|| {
let mut h = new_map();
for hdr in &super::STD[0..8] {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&super::STD[0]));
})
});
bench!(set_10_get_1_std(new_map, b) {
b.iter(|| {
let mut h = new_map();
for hdr in &super::STD[0..10] {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&super::STD[0]));
})
});
bench!(set_20_get_1_std(new_map, b) {
b.iter(|| {
let mut h = new_map();
for hdr in &super::STD[0..20] {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&super::STD[0]));
})
});
bench!(get_10_custom_short(new_map, b) {
let hdrs = custom_hdr(20);
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), hdr.as_str().to_string());
}
b.iter(|| {
for hdr in &hdrs[..10] {
test::black_box(h.get(hdr));
}
})
});
bench!(set_10_get_1_custom_short(new_map, b) {
let hdrs = custom_hdr(10);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&hdrs[0]));
})
});
bench!(set_10_get_1_custom_med(new_map, b) {
let hdrs = super::med_custom_hdr(10);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&hdrs[0]));
})
});
bench!(set_10_get_1_custom_long(new_map, b) {
let hdrs = super::long_custom_hdr(10);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&hdrs[0]));
})
});
bench!(set_10_get_1_custom_very_long(new_map, b) {
let hdrs = super::very_long_custom_hdr(10);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&hdrs[0]));
})
});
bench!(set_20_get_1_custom_short(new_map, b) {
let hdrs = custom_hdr(20);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&hdrs[0]));
})
});
bench!(set_20_get_1_custom_med(new_map, b) {
let hdrs = super::med_custom_hdr(20);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&hdrs[0]));
})
});
bench!(set_20_get_1_custom_long(new_map, b) {
let hdrs = super::long_custom_hdr(20);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&hdrs[0]));
})
});
bench!(set_20_get_1_custom_very_long(new_map, b) {
let hdrs = super::very_long_custom_hdr(20);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
test::black_box(h.get(&hdrs[0]));
})
});
bench!(insert_all_std_headers(new_map, b) {
b.iter(|| {
let mut h = new_map();
for hdr in super::STD {
test::black_box(h.insert(hdr.clone(), "foo"));
}
})
});
bench!(insert_79_custom_std_headers(new_map, b) {
let hdrs = super::custom_std(79);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
h.insert(hdr.clone(), "foo");
}
})
});
bench!(insert_100_custom_headers(new_map, b) {
let hdrs = custom_hdr(100);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
test::black_box(h.insert(hdr.clone(), "foo"));
}
})
});
bench!(insert_500_custom_headers(new_map, b) {
let hdrs = custom_hdr(500);
b.iter(|| {
let mut h = new_map();
for hdr in &hdrs {
test::black_box(h.insert(hdr.clone(), "foo"));
}
})
});
bench!(insert_one_15_char_header(new_map, b) {
let hdr: HeaderName = "abcd-abcd-abcde"
.parse().unwrap();
b.iter(|| {
let mut h = new_map();
h.insert(hdr.clone(), "hello");
test::black_box(h);
})
});
bench!(insert_one_25_char_header(new_map, b) {
let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcde"
.parse().unwrap();
b.iter(|| {
let mut h = new_map();
h.insert(hdr.clone(), "hello");
test::black_box(h);
})
});
bench!(insert_one_50_char_header(new_map, b) {
let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcde"
.parse().unwrap();
b.iter(|| {
let mut h = new_map();
h.insert(hdr.clone(), "hello");
test::black_box(h);
})
});
bench!(insert_one_100_char_header(new_map, b) {
let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcdeabcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcde"
.parse().unwrap();
b.iter(|| {
let mut h = new_map();
h.insert(hdr.clone(), "hello");
test::black_box(h);
})
});
const HN_HDRS: [(&'static str, &'static str); 11] = [
("Date", "Fri, 27 Jan 2017 23:00:00 GMT"),
("Content-Type", "text/html; charset=utf-8"),
("Transfer-Encoding", "chunked"),
("Connection", "keep-alive"),
("Set-Cookie", "__cfduid=dbdfbbe3822b61cb8750ba37d894022151485558000; expires=Sat, 27-Jan-18 23:00:00 GMT; path=/; domain=.ycombinator.com; HttpOnly"),
("Vary", "Accept-Encoding"),
("Cache-Control", "private"),
("X-Frame-Options", "DENY"),
("Strict-Transport-Security", "max-age=31556900; includeSubDomains"),
("Server", "cloudflare-nginx"),
("CF-RAY", "327fd1809f3c1baf-SEA"),
];
bench!(hn_hdrs_set_8_get_many(new_map, b) {
let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS[..8].iter()
.map(|&(name, val)| (name.parse().unwrap(), val))
.collect();
b.iter(|| {
let mut h = new_map();
for &(ref name, val) in hdrs.iter() {
h.insert(name.clone(), val);
}
for _ in 0..15 {
test::black_box(h.get(&CONTENT_LENGTH));
test::black_box(h.get(&VARY));
}
});
});
bench!(hn_hdrs_set_8_get_miss(new_map, b) {
let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS[..8].iter()
.map(|&(name, val)| (name.parse().unwrap(), val))
.collect();
let miss: HeaderName = "x-wat".parse().unwrap();
b.iter(|| {
let mut h = new_map();
for &(ref name, val) in hdrs.iter() {
h.insert(name.clone(), val);
}
test::black_box(h.get(&CONTENT_LENGTH));
test::black_box(h.get(&miss));
});
});
bench!(hn_hdrs_set_11_get_with_miss(new_map, b) {
let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS.iter()
.map(|&(name, val)| (name.parse().unwrap(), val))
.collect();
let miss: HeaderName = "x-wat".parse().unwrap();
b.iter(|| {
let mut h = new_map();
for &(ref name, val) in hdrs.iter() {
h.insert(name.clone(), val);
}
for _ in 0..10 {
test::black_box(h.get(&CONTENT_LENGTH));
test::black_box(h.get(&VARY));
test::black_box(h.get(&miss));
}
});
});
use http::header::*;
fn custom_hdr(n: usize) -> Vec<HeaderName> {
(0..n).map(|i| {
let s = format!("x-custom-{}", i);
s.parse().unwrap()
}).collect()
}
fn med_custom_hdr(n: usize) -> Vec<HeaderName> {
(0..n).map(|i| {
let s = format!("content-length-{}", i);
s.parse().unwrap()
}).collect()
}
fn long_custom_hdr(n: usize) -> Vec<HeaderName> {
(0..n).map(|i| {
let s = format!("access-control-allow-headers-{}", i);
s.parse().unwrap()
}).collect()
}
fn very_long_custom_hdr(n: usize) -> Vec<HeaderName> {
(0..n).map(|i| {
let s = format!("access-control-allow-access-control-allow-headers-{}", i);
s.parse().unwrap()
}).collect()
}
fn custom_std(n: usize) -> Vec<HeaderName> {
(0..n).map(|i| {
let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
s.parse().unwrap()
}).collect()
}
const STD: &'static [HeaderName] = &[
ACCEPT,
ACCEPT_CHARSET,
ACCEPT_ENCODING,
ACCEPT_LANGUAGE,
ACCEPT_RANGES,
ACCESS_CONTROL_ALLOW_CREDENTIALS,
ACCESS_CONTROL_ALLOW_HEADERS,
ACCESS_CONTROL_ALLOW_METHODS,
ACCESS_CONTROL_ALLOW_ORIGIN,
ACCESS_CONTROL_EXPOSE_HEADERS,
ACCESS_CONTROL_MAX_AGE,
ACCESS_CONTROL_REQUEST_HEADERS,
ACCESS_CONTROL_REQUEST_METHOD,
AGE,
ALLOW,
ALT_SVC,
AUTHORIZATION,
CACHE_CONTROL,
CONNECTION,
CONTENT_DISPOSITION,
CONTENT_ENCODING,
CONTENT_LANGUAGE,
CONTENT_LENGTH,
CONTENT_LOCATION,
CONTENT_RANGE,
CONTENT_SECURITY_POLICY,
CONTENT_SECURITY_POLICY_REPORT_ONLY,
CONTENT_TYPE,
COOKIE,
DNT,
DATE,
ETAG,
EXPECT,
EXPIRES,
FORWARDED,
FROM,
HOST,
IF_MATCH,
IF_MODIFIED_SINCE,
IF_NONE_MATCH,
IF_RANGE,
IF_UNMODIFIED_SINCE,
LAST_MODIFIED,
LINK,
LOCATION,
MAX_FORWARDS,
ORIGIN,
PRAGMA,
PROXY_AUTHENTICATE,
PROXY_AUTHORIZATION,
PUBLIC_KEY_PINS,
PUBLIC_KEY_PINS_REPORT_ONLY,
RANGE,
REFERER,
REFERRER_POLICY,
REFRESH,
RETRY_AFTER,
SERVER,
SET_COOKIE,
STRICT_TRANSPORT_SECURITY,
TE,
TRAILER,
TRANSFER_ENCODING,
USER_AGENT,
UPGRADE,
UPGRADE_INSECURE_REQUESTS,
VARY,
VIA,
WARNING,
WWW_AUTHENTICATE,
X_CONTENT_TYPE_OPTIONS,
X_DNS_PREFETCH_CONTROL,
X_FRAME_OPTIONS,
X_XSS_PROTECTION,
];