Skip to content

Commit

Permalink
Make HeaderName::from_static const
Browse files Browse the repository at this point in the history
... plus some clean-up.

It was only after I came up with the `const fn
StandardHeader::from_bytes() -> Option<StandardHeader>` scheme 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 hyperium#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 `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 8.5 months old, so hopefully
this isn't too controversial!
  • Loading branch information
jeddenlea committed Aug 20, 2021
1 parent c8cc69e commit 5cb161f
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- stable
- beta
- nightly
- 1.46.0
- 1.49.0

include:
- rust: nightly
Expand Down
139 changes: 139 additions & 0 deletions benches/header_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,128 @@ fn make_all_known_headers() -> Vec<Vec<u8>> {
]
}

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";
Expand All @@ -138,6 +260,14 @@ fn header_name_easy(b: &mut Bencher) {
});
}

#[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";
Expand All @@ -155,3 +285,12 @@ fn header_name_various(b: &mut Bencher) {
}
});
}

#[bench]
fn header_name_from_static(b: &mut Bencher) {
b.iter(|| {
for name in ALL_KNOWN_HEADERS {
HeaderName::from_static(name);
}
});
}
2 changes: 1 addition & 1 deletion src/header/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ macro_rules! standard_headers {
#[inline]
fn as_str(&self) -> &'static str {
match *self {
// Safety: test_parse_standard_headers ensures our static &[u8]s are &str-safe.
// Safety: test_parse_standard_headers ensures these &[u8]s are &str-safe.
$(
StandardHeader::$konst => unsafe { std::str::from_utf8_unchecked( $name_bytes ) },
)+
Expand Down

0 comments on commit 5cb161f

Please sign in to comment.