-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Pre-allocate in fs::read and fs::read_string #47324
Conversation
src/libstd/fs.rs
Outdated
// Allocate one extra byte so the buffer doesn't need to grow before the final `read` call at | ||
// the end of the file. Don't worry about `usize` overflow because this will fail anyway if | ||
// the file doesn't fit into memory. | ||
let mut bytes = Vec::with_capacity(metadata(&path)?.len() as usize + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there contexts/weird files where the metadata lookup won't work but the file read will?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not totally certain. I based this on #45928 (comment):
You can always return 0 if something went wrong, but it seems like it's nice to not throw away those errors. I kind of doubt that reads would succeed if you can't stat the file anymore.
but I do think it would be reasonable to just start with an empty buffer if the stat call fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that starting with an empty buffer if the stat call fails is probably the right thing to do. It's potentially worth pointing out that it seems like this may not be faster (#35844 (comment)) based on past benchmarks so maybe we shouldn't do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think those numbers may no longer be accurate - we no longer zero the buffer before reading into it for Files, and read_to_end has been tweaked a bit to behave differently. #45928 has some benchmarks.
Here are before/after benchmark results from my Linux x86_64 laptop with SSD with a hot cache. The
|
@bors r+ |
📌 Commit 1745f43 has been approved by |
@bors r=sfackler |
📌 Commit 44912bf has been approved by |
Updated to fall back to an empty buffer if |
@bors r+ |
💡 This pull request was already approved, no need to approve it again.
|
📌 Commit 44912bf has been approved by |
fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize { | ||
// Allocate one extra byte so the buffer doesn't need to grow before the | ||
// final `read` call at the end of the file. Don't worry about `usize` | ||
// overflow because reading will fail regardless in that case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does "fail regardless" here mean Result::Err
or panic?
m.len() as usize + 1
can panic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will panic in RawVec code when requested capacity exceeds isize::MAX
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(or more likely, abort due to out-of-memory sometime before that)
Pre-allocate in fs::read and fs::read_string This is a simpler alternative to rust-lang#46340 and rust-lang#45928, as requested by the libs team.
Use the new fs_read_write functions in rustc internals Uses `fs::read` and `fs::write` (added by rust-lang#45837) where appropriate, to simplify code and dog-food these new APIs. This also improves performance, when combined with rust-lang#47324.
Pre-allocate in fs::read and fs::read_string This is a simpler alternative to rust-lang#46340 and rust-lang#45928, as requested by the libs team.
Use the new fs_read_write functions in rustc internals Uses `fs::read` and `fs::write` (added by rust-lang#45837) where appropriate, to simplify code and dog-food these new APIs. This also improves performance, when combined with rust-lang#47324.
Pre-allocate in fs::read and fs::read_string This is a simpler alternative to rust-lang#46340 and rust-lang#45928, as requested by the libs team.
Use the new fs_read_write functions in rustc internals Uses `fs::read` and `fs::write` (added by rust-lang#45837) where appropriate, to simplify code and dog-food these new APIs. This also improves performance, when combined with rust-lang#47324.
Should this use a sequence of calls to do Should I file a bug to track this? |
@alex That sounds like a good idea. (This can use the |
This is a simpler alternative to #46340 and #45928, as requested by the libs team.