diff options
| author | Kyle Huey <khuey@kylehuey.com> | 2017-12-03 20:45:12 -0800 |
|---|---|---|
| committer | Kyle Huey <khuey@kylehuey.com> | 2017-12-03 20:45:12 -0800 |
| commit | 02c1862fb55c6ae4198038b1b317bcdd06e395d1 (patch) | |
| tree | 3dc542449e75d299a09217a504cae3b3e6f0aef1 /src/libstd | |
| parent | f2b11f30b2946119c23594bc2b3bec3c38d3ae9a (diff) | |
| download | rust-02c1862fb55c6ae4198038b1b317bcdd06e395d1.tar.gz rust-02c1862fb55c6ae4198038b1b317bcdd06e395d1.zip | |
Add a specialization of read_exact for Cursor.
The read_exact implementation for &[u8] is optimized and usually allows LLVM to reduce a read_exact call for small numbers of bytes to a bounds check and a register load instead of a generic memcpy. On a workload I have that decompresses, deserializes (via bincode), and processes some data, this leads to a 40% speedup by essentially eliminating the deserialization overhead entirely.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/io/cursor.rs | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 32a92145aaf..b5ea5531b65 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -230,6 +230,13 @@ impl<T> Read for Cursor<T> where T: AsRef<[u8]> { Ok(n) } + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + let n = buf.len(); + Read::read_exact(&mut self.fill_buf()?, buf)?; + self.pos += n as u64; + Ok(()) + } + #[inline] unsafe fn initializer(&self) -> Initializer { Initializer::nop() @@ -476,6 +483,24 @@ mod tests { } #[test] + fn test_read_exact() { + let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; + let reader = &mut &in_buf[..]; + let mut buf = []; + assert!(reader.read_exact(&mut buf).is_ok()); + let mut buf = [8]; + assert!(reader.read_exact(&mut buf).is_ok()); + assert_eq!(buf[0], 0); + assert_eq!(reader.len(), 7); + let mut buf = [0, 0, 0, 0, 0, 0, 0]; + assert!(reader.read_exact(&mut buf).is_ok()); + assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7]); + assert_eq!(reader.len(), 0); + let mut buf = [0]; + assert!(reader.read_exact(&mut buf).is_err()); + } + + #[test] fn test_buf_reader() { let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; let mut reader = Cursor::new(&in_buf[..]); |
