Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make HeaderName::from_static const #499

Merged
merged 1 commit into from
Apr 16, 2022
Merged

Conversation

jeddenlea
Copy link
Contributor

@jeddenlea jeddenlea commented Aug 20, 2021

... 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!

@seanmonstar
Copy link
Member

@carllerche you wrote the eq! stuff, any insight on instances where it's worth keeping?

@carllerche
Copy link
Collaborator

It's been a while. My recollection is this was to optimize header parsing. If there are benchmarks still checking parse speed and they aren't impacted, then it is probably fine.

@jeddenlea
Copy link
Contributor Author

Using cargo +nightly bench header_name, before:

test header_name_bad     ... bench:           9 ns/iter (+/- 0)
test header_name_easy    ... bench:          10 ns/iter (+/- 0)
test header_name_various ... bench:       3,885 ns/iter (+/- 875)

and with this change,

test header_name_bad         ... bench:          11 ns/iter (+/- 1)
test header_name_custom      ... bench:          81 ns/iter (+/- 5)
test header_name_easy        ... bench:          11 ns/iter (+/- 0)
test header_name_from_static ... bench:       1,024 ns/iter (+/- 483)
test header_name_various     ... bench:       3,829 ns/iter (+/- 288)

@jeddenlea
Copy link
Contributor Author

.... and just to be complete, here are the two new benchmarks cut out and run on 0.2.6,

test header_name_custom      ... bench:          79 ns/iter (+/- 7)
test header_name_from_static ... bench:       1,241 ns/iter (+/- 72)

So, maybe only a 20% improvement instead of a 33% improvement, but still!

jeddenlea added a commit to jeddenlea/http that referenced this pull request Apr 1, 2022
@jeddenlea jeddenlea mentioned this pull request Apr 1, 2022
@npmccallum
Copy link

@jeddenlea @seanmonstar FYI - const_panic is now stable in 1.57.0.

panic!("invalid header name")
}
}
#[allow(unconditional_panic)] // required for the panic circumventon
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D'oh, I copied the same error fixed in #532

jeddenlea added a commit to jeddenlea/http that referenced this pull request Apr 6, 2022
Copy link
Member

@LucioFranco LucioFranco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall lgtm w/ the benches you posted.

/// | ^^^^^^^^^^^^^^^^^^
/// | |
/// | index out of bounds: the length is 0 but the index is 0
/// | inside `fastly::http::HeaderName::from_static` at http/src/header/name.rs:1241:13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean to include fastly here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// | inside `fastly::http::HeaderName::from_static` at http/src/header/name.rs:1241:13
/// | inside `http::HeaderName::from_static` at http/src/header/name.rs:1241:13

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, no, I did not. I'm so used to seeing it I didn't even notice. I'm going to force push that change.

Copy link
Member

@seanmonstar seanmonstar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the one proposed change, we can merge this :)

... 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!
@jeddenlea jeddenlea requested a review from seanmonstar April 15, 2022 23:49
jeddenlea added a commit to jeddenlea/http that referenced this pull request Apr 15, 2022
@seanmonstar seanmonstar merged commit d8b35db into hyperium:master Apr 16, 2022
@@ -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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems kinda strange that the MSRV was bumped without any notice in the PR description or in the release notes, no? Makes it somewhat hard to handle updates in downstream projects.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This project follows the msrv of tokio https://github.com/tokio-rs/tokio/#supported-rust-versions but we should add it to the changelog. Good catch.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem like it? tokio supports previous versions with point releases, allowing users with an older rustc to keep using tokio with bugfixes provided even if they have to ignore new versions. It looks like this crate is updated in point releases to have a new MSRV. In this case I wasn't able to use a down-down-downstream crate because it no longer built using system rustc on popular distros.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is mainly due to a few reasons, tokio is already 1.0 and thus at the time of 1.0 we try to support everyone. While this crate is below 1.0 so the guarantees are different. I assume it should be possible to pin the version of http though for your crate?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, understood, and I can pin for now, I was just noting that you said "this project follow the msrv of tokio" which isn't really accurate, given tokio has great support for broadly-available/deployed versions of rustc but I don't believe such support exists here (ie you miss bugfixes if you don't use rustup).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants