Rollup merge of #60656 - petertodd:2019-inline-cursor-over-slice, r=sfackler
Inline some Cursor calls for slices (Partially) brings back https://github.com/rust-lang/rust/pull/33921 I've noticed in some serialization code I was writing that writes to slices produce much, much, worse code than you'd expect even with optimizations turned on. For example, you'd expect something like this to be zero cost: ``` use std::io::{self, Cursor, Write}; pub fn serialize((a, b): (u64, u64)) -> [u8;8+8] { let mut r = [0u8;16]; { let mut w = Cursor::new(&mut r[..]); w.write(&a.to_le_bytes()).unwrap(); w.write(&b.to_le_bytes()).unwrap(); } r } ``` ...but it compiles down to [dozens of instructions](https://rust.godbolt.org/z/bdwDzb) because the `slice_write()` calls aren't inlined, which in turn means `unwrap()` can't be optimized away, and so on. To be clear, this pull-req isn't sufficient by itself: if we want to go down that path we also need to add `#[inline]`'s to the default implementations for functions like `write_all()` in the `Write` trait and so on, or implement them separately in the `Cursor` impls. But I figured I'd start a conversation about what tradeoffs we're expecting here.
This commit is contained in:
commit
671dd0992f
@ -265,6 +265,7 @@ impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> {
|
||||
}
|
||||
|
||||
// Non-resizing write implementation
|
||||
#[inline]
|
||||
fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> {
|
||||
let pos = cmp::min(*pos_mut, slice.len() as u64);
|
||||
let amt = (&mut slice[(pos as usize)..]).write(buf)?;
|
||||
@ -272,6 +273,7 @@ fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<us
|
||||
Ok(amt)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_write_vectored(
|
||||
pos_mut: &mut u64,
|
||||
slice: &mut [u8],
|
||||
@ -341,6 +343,7 @@ impl Write for Cursor<&mut [u8]> {
|
||||
slice_write_vectored(&mut self.pos, self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
@ -354,6 +357,7 @@ impl Write for Cursor<&mut Vec<u8>> {
|
||||
vec_write_vectored(&mut self.pos, self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
@ -367,6 +371,7 @@ impl Write for Cursor<Vec<u8>> {
|
||||
vec_write_vectored(&mut self.pos, &mut self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
@ -382,6 +387,7 @@ impl Write for Cursor<Box<[u8]>> {
|
||||
slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user