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 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 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 `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!
  • Loading branch information
jeddenlea committed Dec 17, 2021
1 parent abe6512 commit ba2b432
Show file tree
Hide file tree
Showing 5 changed files with 318 additions and 711 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- nightly
# When updating this value, don't forget to also adjust the
# `rust-version` field in the `Cargo.toml` file.
- 1.46.0
- 1.49.0

include:
- rust: nightly
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ keywords = ["http"]
categories = ["web-programming"]
edition = "2018"
# When updating this value, don't forget to also adjust the GitHub Actions config.
rust-version = "1.46.0"
rust-version = "1.49.0"

[dependencies]
bytes = "1"
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/byte_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl ByteStr {
}

#[inline]
pub fn from_static(val: &'static str) -> ByteStr {
pub const fn from_static(val: &'static str) -> ByteStr {
ByteStr {
// Invariant: val is a str so contains vaid UTF-8.
bytes: Bytes::from_static(val.as_bytes()),
Expand Down
Loading

0 comments on commit ba2b432

Please sign in to comment.