-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Remove unnecessary Option
from BufWriter
#36336
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
Ok(()) => Ok(self.inner.take().unwrap()) | ||
Ok(()) => { | ||
let inner = unsafe { ptr::read(&self.inner) }; | ||
mem::forget(self); |
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.
You are leaking the buffer here.
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.
Good catch!
Ok(()) => unsafe { | ||
// use `ptr::read` to extract the inner writer and circumvent | ||
// our `Drop` implementation | ||
mem::replace(&mut self.buf, Vec::new()); |
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.
To be honest, I find using mem::replace
here pretty confusing - in my opinion ptr::read
ing the buffer (maybe with a comment why) would convey the intent much better (dropping the buffer), especially since we rely on the fact that Vec::new()
never allocates (which is document, but still).
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.
Maybe std::ptr::drop_in_place(&mut self.buf)
would be the clearest then (it does what it says), but I still want to favour safe code when it should be equivalent.
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.
Ah, now I understand why you prefer mem::replace
. Both are fine with me I guess, although I think a short comment that buf
is being dropped here probably wouldn't go amiss.
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.
drop_in_place
won't work anymore with the removal of drop flags, right?
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.
Sure it works
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.
Nevermind, I conflated it with read_and_drop
.
On Thu, Sep 8, 2016 at 4:37 PM, bluss notifications@github.com wrote:
In src/libstd/io/buffered.rs
#36336 (comment):@@ -451,7 +453,14 @@ impl<W: Write> BufWriter {
pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter>> {
match self.flush_buf() {
Err(e) => Err(IntoInnerError(self, e)),
Ok(()) => Ok(self.inner.take().unwrap())
Ok(()) => unsafe {
// use `ptr::read` to extract the inner writer and circumvent
// our `Drop` implementation
mem::replace(&mut self.buf, Vec::new());
Sure it works
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rust/pull/36336/files/ea72b7efc9f8a7fc2234264cbc6fc2241f66cd52#r78084035,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAC3nxeWhhJT2ZkrrBbzzvR9e2an8Wp3ks5qoHHzgaJpZM4J3ebB
.
Thanks for the PR @apasel422! I'm curious though if we could get some perf numbers for this though? This is something that, while possible, is tricky to write, so it's best to have strong rationale for unsafe code here. |
I was trying to look at perf only to discover that BufWriter is hit by extend_from_slice slowness too (#33518). (Let's fix |
Ok that issue is resolved, great. I haven't looked at this in detail yet, but it's not in any inner loop, the option is only touched whenever the buffer is full. So it might be that it's not a great difference? |
My assumption is that this will be very difficult to get to show up in practice, and this is tricky enough that I'm not currently convinced the unsafety is worth it. If there's a strong perf case for doing it though, then I could be swayed! |
Discussed during libs triage our conclusion was to hold off on this until we can come up with some convincing benchmarks. @apasel422 you wouldn't happen to have any on hand would you? |
@alexcrichton I don't have any benchmarks right now. I'll reopen this once I do. |
I think I'm interested in implementing this, trying to do so without unsafe code if possible. @apasel422 ping from triage |
I'm getting these results for these benchmarks:
|
My implementation is nearly the same, but
|
Closes #36319