-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Avoid repeated re-initialization of the BufReader buffer #102760
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
(rust-highfive has picked a reviewer for you, use r? to override) |
How difficult is it to write a test here? I suspect it would be pretty annoying, but maybe we can reasonably do it with some helper cfg(test) exposed bits... |
I'm proposing that rustc-perf add a runtime benchmark that targets a reasonably-real-world use case that tickles this code path: rust-lang/rustc-perf#1460 Does that assuage your concern about testing? |
I guess it's not the worst way to do this, though it is a pretty weak signal (and doesn't stop us from landing regressions since runtime benchmarks are a ways away from automatically running). Is it hard for us to directly expose the initialized variable in cfg(test) so we can just assert that it behaves properly? I'm okay approving this (and also going to nominate for backport as a bad regression) without that, but it would definitely make me feel better to have that direct feedback mechanism. |
811b6f8
to
95ae993
Compare
I added a test which asserts that the I'm not entirely sure benchmarks are a weaker signal than any kind of unit test we can write here. The problem reported was that some code became slower due to re-initialization of the buffer. This test is no protection at all against that. We don't have a way to detect that those bytes in the possibly-uninitialized region of the So, if you have a better thing to test for, I would love to hear about it. |
Shouldn't we also replace the manual fill with a memset ( |
It will at least get flagged eventually. It will not stop a nightly regression from landing, but it certainly would stop a stable regression. |
I wouldn't object to improving the manual fill implementation, but I feel like that's another optimization on the side where here I'm just trying to fix the regression? |
I am happy with this PR now, happy to leave future improvements to the future. @bors r+ |
Rollup of 6 pull requests Successful merges: - rust-lang#102300 (Use a macro to not have to copy-paste `ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp)).0` everywhere) - rust-lang#102475 (unsafe keyword: trait examples and unsafe_op_in_unsafe_fn update) - rust-lang#102760 (Avoid repeated re-initialization of the BufReader buffer) - rust-lang#102764 (Check `WhereClauseReferencesSelf` after all other object safety checks) - rust-lang#102779 (Fix `type_of` ICE) - rust-lang#102780 (run Miri CI when std::sys changes) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Use memset to initialize readbuf The write loop was found to be slow in rust-lang#102727 The proper fix is in rust-lang#102760 but this might still help debug builds and code running under miri by using the write_bytes intrinsic instead of writing one byte at a time.
[beta] backports - Use rebind instead of dummy binder in `SameTypeModuloInfer` relation rust-lang#102059 - Add missing space between notable trait tooltip and where clause rust-lang#102107 - Avoid repeated re-initialization of the BufReader buffer rust-lang#102760 - Ensure enum cast moves rust-lang#103016 - Fix `TyKind::is_simple_path` rust-lang#103176 - Do anonymous lifetimes remapping correctly for nested rpits rust-lang#103205 - [beta] Cargo backport 1.65.0 rust-lang#103303 - linker: Fix weak lang item linking with combination windows-gnu + LLD + LTO rust-lang#103092 r? `@ghost`
Fixes #102727
We accidentally removed this in #98748. It looks so redundant. But it isn't.
The default
Read::read_buf
will defensively initialize the whole buffer, if any of it is indicated to be uninitialized. In uses where reads from the wrappedRead
impl completely fill theBufReader
,initialized
andfilled
are the same, and this extra member isn't required. But in the reported issue, theBufReader
wraps aRead
impl which will never fill the whole buffer. So the defaultRead::read_buf
implementation repeatedly re-initializes the extra space in the buffer.This adds back the extra
initialized
member, which ensures that the defaultRead::read_buf
only zero-initialized the buffer once, and I've tried to add a comment which explains this whole situation.