Skip to content

Commit 50642bd

Browse files
committed
Make HeaderName::from_static const
... 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!
1 parent c28945c commit 50642bd

File tree

5 files changed

+318
-711
lines changed

5 files changed

+318
-711
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- nightly
2222
# When updating this value, don't forget to also adjust the
2323
# `rust-version` field in the `Cargo.toml` file.
24-
- 1.46.0
24+
- 1.49.0
2525

2626
include:
2727
- rust: nightly

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ keywords = ["http"]
2121
categories = ["web-programming"]
2222
edition = "2018"
2323
# When updating this value, don't forget to also adjust the GitHub Actions config.
24-
rust-version = "1.46.0"
24+
rust-version = "1.49.0"
2525

2626
[dependencies]
2727
bytes = "1"

benches/header_name.rs

+139
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,128 @@ fn make_all_known_headers() -> Vec<Vec<u8>> {
130130
]
131131
}
132132

133+
static ALL_KNOWN_HEADERS: &[&str] = &[
134+
// Standard request headers
135+
"a-im",
136+
"accept",
137+
"accept-charset",
138+
"accept-datetime",
139+
"accept-encoding",
140+
"accept-language",
141+
"access-control-request-method",
142+
"authorization",
143+
"cache-control",
144+
"connection",
145+
"permanent",
146+
"content-length",
147+
"content-md5",
148+
"content-type",
149+
"cookie",
150+
"date",
151+
"expect",
152+
"forwarded",
153+
"from",
154+
"host",
155+
"permanent",
156+
"http2-settings",
157+
"if-match",
158+
"if-modified-since",
159+
"if-none-match",
160+
"if-range",
161+
"if-unmodified-since",
162+
"max-forwards",
163+
"origin",
164+
"pragma",
165+
"proxy-authorization",
166+
"range",
167+
"referer",
168+
"te",
169+
"user-agent",
170+
"upgrade",
171+
"via",
172+
"warning",
173+
// common_non_standard
174+
"upgrade-insecure-requests",
175+
"upgrade-insecure-requests",
176+
"x-requested-with",
177+
"dnt",
178+
"x-forwarded-for",
179+
"x-forwarded-host",
180+
"x-forwarded-proto",
181+
"front-end-https",
182+
"x-http-method-override",
183+
"x-att-deviceid",
184+
"x-wap-profile",
185+
"proxy-connection",
186+
"x-uidh",
187+
"x-csrf-token",
188+
"x-request-id",
189+
"x-correlation-id",
190+
"save-data",
191+
// standard_response_headers
192+
"accept-patch",
193+
"accept-ranges",
194+
"access-control-allow-credentials",
195+
"access-control-allow-headers",
196+
"access-control-allow-methods",
197+
"access-control-allow-origin",
198+
"access-control-expose-headers",
199+
"access-control-max-age",
200+
"age",
201+
"allow",
202+
"alt-svc",
203+
"cache-control",
204+
"connection",
205+
"content-disposition",
206+
"content-encoding",
207+
"content-language",
208+
"content-length",
209+
"content-location",
210+
"content-md5",
211+
"content-range",
212+
"content-type",
213+
"date",
214+
"delta-base",
215+
"etag",
216+
"expires",
217+
"im",
218+
"last-modified",
219+
"link",
220+
"location",
221+
"p3p",
222+
"permanent",
223+
"pragma",
224+
"proxy-authenticate",
225+
"public-key-pins",
226+
"retry-after",
227+
"server",
228+
"set-cookie",
229+
"strict-transport-security",
230+
"tk",
231+
"trailer",
232+
"transfer-encoding",
233+
"upgrade",
234+
"vary",
235+
"via",
236+
"warning",
237+
"www-authenticate",
238+
"x-frame-options",
239+
// common_non_standard_response
240+
"content-security-policy",
241+
"refresh",
242+
"status",
243+
"timing-allow-origin",
244+
"x-content-duration",
245+
"x-content-security-policy",
246+
"x-content-type-options",
247+
"x-correlation-id",
248+
"x-powered-by",
249+
"x-request-id",
250+
"x-ua-compatible",
251+
"x-webkit-csp",
252+
"x-xss-protection",
253+
];
254+
133255
#[bench]
134256
fn header_name_easy(b: &mut Bencher) {
135257
let name = b"Content-type";
@@ -138,6 +260,14 @@ fn header_name_easy(b: &mut Bencher) {
138260
});
139261
}
140262

263+
#[bench]
264+
fn header_name_custom(b: &mut Bencher) {
265+
let name = b"Foo-Bar-Baz-Blah";
266+
b.iter(|| {
267+
HeaderName::from_bytes(&name[..]).unwrap();
268+
});
269+
}
270+
141271
#[bench]
142272
fn header_name_bad(b: &mut Bencher) {
143273
let name = b"bad header name";
@@ -155,3 +285,12 @@ fn header_name_various(b: &mut Bencher) {
155285
}
156286
});
157287
}
288+
289+
#[bench]
290+
fn header_name_from_static(b: &mut Bencher) {
291+
b.iter(|| {
292+
for name in ALL_KNOWN_HEADERS {
293+
HeaderName::from_static(name);
294+
}
295+
});
296+
}

src/byte_str.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl ByteStr {
1818
}
1919

2020
#[inline]
21-
pub fn from_static(val: &'static str) -> ByteStr {
21+
pub const fn from_static(val: &'static str) -> ByteStr {
2222
ByteStr {
2323
// Invariant: val is a str so contains vaid UTF-8.
2424
bytes: Bytes::from_static(val.as_bytes()),

0 commit comments

Comments
 (0)