diff options
| author | bors <bors@rust-lang.org> | 2017-12-04 10:02:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-12-04 10:02:48 +0000 |
| commit | c16f480fa6eb6b28f51c7218347bcaf1377dedea (patch) | |
| tree | 3a209104c80c17b525a626b0c80d72a3ecd3a56d /src/libstd | |
| parent | fdfbcf85d55da97ed1a00823510b876018047aaf (diff) | |
| parent | 02c1862fb55c6ae4198038b1b317bcdd06e395d1 (diff) | |
| download | rust-c16f480fa6eb6b28f51c7218347bcaf1377dedea.tar.gz rust-c16f480fa6eb6b28f51c7218347bcaf1377dedea.zip | |
Auto merge of #46485 - khuey:cursor-read_exact, r=Manishearth
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[..]); |
