Files
Jed Denlea 49d19ff8a4 Make HeaderName::from_static const (#499)
... plus some clean-up.

It was only after I came up with the scheme using
`const fn from_bytes(&[u8]) -> Option<StandardHeader>`
that I noticed the debug+wasm32-wasi version of `parse_hdr`, which had
something very similar.

While cleaning up that function, I realized it still would still panic
if an attempted name was too long, which had been fixed for all other
targets and profiles in #433.  Then, I thought it would be worth seeing
if the use of `eq!` in the primary version of `parse_hdr` still made any
difference.

And, it would not appear so. At least not on x86_64, nor wasm32-wasi run
via wasmtime.  I've run the benchmarks a number of times now, and it
seems the only significant performance change anywhere is actually that
of `HeaderName::from_static` itself, which now seems to run in about 2/3
the time on average.

Unfortunately, `const fn` still cannot `panic!`, but I've followed the
lead from `HeaderValue::from_static`.  While that version required 1.46,
this new function requires 1.49.  That is almost 8 months old, so
hopefully this isn't too controversial!
2022-04-16 08:40:20 -07:00

297 lines
7.1 KiB
Rust

#![feature(test)]
extern crate bytes;
extern crate http;
extern crate test;
use http::header::HeaderName;
use test::Bencher;
fn make_all_known_headers() -> Vec<Vec<u8>> {
// Standard request headers
vec![b"A-IM".to_vec(),
b"Accept".to_vec(),
b"Accept-Charset".to_vec(),
b"Accept-Datetime".to_vec(),
b"Accept-Encoding".to_vec(),
b"Accept-Language".to_vec(),
b"Access-Control-Request-Method".to_vec(),
b"Authorization".to_vec(),
b"Cache-Control".to_vec(),
b"Connection".to_vec(),
b"Permanent".to_vec(),
b"Content-Length".to_vec(),
b"Content-MD5".to_vec(),
b"Content-Type".to_vec(),
b"Cookie".to_vec(),
b"Date".to_vec(),
b"Expect".to_vec(),
b"Forwarded".to_vec(),
b"From".to_vec(),
b"Host".to_vec(),
b"Permanent".to_vec(),
b"HTTP2-Settings".to_vec(),
b"If-Match".to_vec(),
b"If-Modified-Since".to_vec(),
b"If-None-Match".to_vec(),
b"If-Range".to_vec(),
b"If-Unmodified-Since".to_vec(),
b"Max-Forwards".to_vec(),
b"Origin".to_vec(),
b"Pragma".to_vec(),
b"Proxy-Authorization".to_vec(),
b"Range".to_vec(),
b"Referer".to_vec(),
b"TE".to_vec(),
b"User-Agent".to_vec(),
b"Upgrade".to_vec(),
b"Via".to_vec(),
b"Warning".to_vec(),
// common_non_standard
b"Upgrade-Insecure-Requests".to_vec(),
b"Upgrade-Insecure-Requests".to_vec(),
b"X-Requested-With".to_vec(),
b"DNT".to_vec(),
b"X-Forwarded-For".to_vec(),
b"X-Forwarded-Host".to_vec(),
b"X-Forwarded-Proto".to_vec(),
b"Front-End-Https".to_vec(),
b"X-Http-Method-Override".to_vec(),
b"X-ATT-DeviceId".to_vec(),
b"X-Wap-Profile".to_vec(),
b"Proxy-Connection".to_vec(),
b"X-UIDH".to_vec(),
b"X-Csrf-Token".to_vec(),
b"X-Request-ID".to_vec(),
b"X-Correlation-ID".to_vec(),
b"Save-Data".to_vec(),
// standard_response_headers
b"Accept-Patch".to_vec(),
b"Accept-Ranges".to_vec(),
b"Access-Control-Allow-Credentials".to_vec(),
b"Access-Control-Allow-Headers".to_vec(),
b"Access-Control-Allow-Methods".to_vec(),
b"Access-Control-Allow-Origin".to_vec(),
b"Access-Control-Expose-Headers".to_vec(),
b"Access-Control-Max-Age".to_vec(),
b"Age".to_vec(),
b"Allow".to_vec(),
b"Alt-Svc".to_vec(),
b"Cache-Control".to_vec(),
b"Connection".to_vec(),
b"Content-Disposition".to_vec(),
b"Content-Encoding".to_vec(),
b"Content-Language".to_vec(),
b"Content-Length".to_vec(),
b"Content-Location".to_vec(),
b"Content-MD5".to_vec(),
b"Content-Range".to_vec(),
b"Content-Type".to_vec(),
b"Date".to_vec(),
b"Delta-Base".to_vec(),
b"ETag".to_vec(),
b"Expires".to_vec(),
b"IM".to_vec(),
b"Last-Modified".to_vec(),
b"Link".to_vec(),
b"Location".to_vec(),
b"P3P".to_vec(),
b"Permanent".to_vec(),
b"Pragma".to_vec(),
b"Proxy-Authenticate".to_vec(),
b"Public-Key-Pins".to_vec(),
b"Retry-After".to_vec(),
b"Server".to_vec(),
b"Set-Cookie".to_vec(),
b"Strict-Transport-Security".to_vec(),
b"Tk".to_vec(),
b"Trailer".to_vec(),
b"Transfer-Encoding".to_vec(),
b"Upgrade".to_vec(),
b"Vary".to_vec(),
b"Via".to_vec(),
b"Warning".to_vec(),
b"WWW-Authenticate".to_vec(),
b"X-Frame-Options".to_vec(),
// common_non_standard_response
b"Content-Security-Policy".to_vec(),
b"Refresh".to_vec(),
b"Status".to_vec(),
b"Timing-Allow-Origin".to_vec(),
b"X-Content-Duration".to_vec(),
b"X-Content-Security-Policy".to_vec(),
b"X-Content-Type-Options".to_vec(),
b"X-Correlation-ID".to_vec(),
b"X-Powered-By".to_vec(),
b"X-Request-ID".to_vec(),
b"X-UA-Compatible".to_vec(),
b"X-WebKit-CSP".to_vec(),
b"X-XSS-Protection".to_vec(),
]
}
static ALL_KNOWN_HEADERS: &[&str] = &[
// Standard request headers
"a-im",
"accept",
"accept-charset",
"accept-datetime",
"accept-encoding",
"accept-language",
"access-control-request-method",
"authorization",
"cache-control",
"connection",
"permanent",
"content-length",
"content-md5",
"content-type",
"cookie",
"date",
"expect",
"forwarded",
"from",
"host",
"permanent",
"http2-settings",
"if-match",
"if-modified-since",
"if-none-match",
"if-range",
"if-unmodified-since",
"max-forwards",
"origin",
"pragma",
"proxy-authorization",
"range",
"referer",
"te",
"user-agent",
"upgrade",
"via",
"warning",
// common_non_standard
"upgrade-insecure-requests",
"upgrade-insecure-requests",
"x-requested-with",
"dnt",
"x-forwarded-for",
"x-forwarded-host",
"x-forwarded-proto",
"front-end-https",
"x-http-method-override",
"x-att-deviceid",
"x-wap-profile",
"proxy-connection",
"x-uidh",
"x-csrf-token",
"x-request-id",
"x-correlation-id",
"save-data",
// standard_response_headers
"accept-patch",
"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",
"age",
"allow",
"alt-svc",
"cache-control",
"connection",
"content-disposition",
"content-encoding",
"content-language",
"content-length",
"content-location",
"content-md5",
"content-range",
"content-type",
"date",
"delta-base",
"etag",
"expires",
"im",
"last-modified",
"link",
"location",
"p3p",
"permanent",
"pragma",
"proxy-authenticate",
"public-key-pins",
"retry-after",
"server",
"set-cookie",
"strict-transport-security",
"tk",
"trailer",
"transfer-encoding",
"upgrade",
"vary",
"via",
"warning",
"www-authenticate",
"x-frame-options",
// common_non_standard_response
"content-security-policy",
"refresh",
"status",
"timing-allow-origin",
"x-content-duration",
"x-content-security-policy",
"x-content-type-options",
"x-correlation-id",
"x-powered-by",
"x-request-id",
"x-ua-compatible",
"x-webkit-csp",
"x-xss-protection",
];
#[bench]
fn header_name_easy(b: &mut Bencher) {
let name = b"Content-type";
b.iter(|| {
HeaderName::from_bytes(&name[..]).unwrap();
});
}
#[bench]
fn header_name_custom(b: &mut Bencher) {
let name = b"Foo-Bar-Baz-Blah";
b.iter(|| {
HeaderName::from_bytes(&name[..]).unwrap();
});
}
#[bench]
fn header_name_bad(b: &mut Bencher) {
let name = b"bad header name";
b.iter(|| {
HeaderName::from_bytes(&name[..]).expect_err("Bad header name");
});
}
#[bench]
fn header_name_various(b: &mut Bencher) {
let all_known_headers = make_all_known_headers();
b.iter(|| {
for name in &all_known_headers{
HeaderName::from_bytes(name.as_slice()).unwrap();
}
});
}
#[bench]
fn header_name_from_static(b: &mut Bencher) {
b.iter(|| {
for name in ALL_KNOWN_HEADERS {
HeaderName::from_static(name);
}
});
}