diff options
| author | Ben Kimock <kimockb@gmail.com> | 2020-12-19 15:02:01 -0500 |
|---|---|---|
| committer | KodrAus <kodraus@hey.com> | 2021-01-17 12:10:39 +1000 |
| commit | 4e27ed3af19e604d7b65e130145fcecdc69fba7a (patch) | |
| tree | 43137963aafb15fe3f7579ac8b4dda6c3433ef2a /library/std/src/io/buffered/bufreader.rs | |
| parent | 8a6518427e11e6dd13d6f39663b82eb4f810ca05 (diff) | |
| download | rust-4e27ed3af19e604d7b65e130145fcecdc69fba7a.tar.gz rust-4e27ed3af19e604d7b65e130145fcecdc69fba7a.zip | |
Add benchmark and fast path for BufReader::read_exact
Diffstat (limited to 'library/std/src/io/buffered/bufreader.rs')
| -rw-r--r-- | library/std/src/io/buffered/bufreader.rs | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 16c18d6e146..8bae3da1273 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -271,6 +271,20 @@ impl<R: Read> Read for BufReader<R> { Ok(nread) } + // Small read_exacts from a BufReader are extremely common when used with a deserializer. + // The default implementation calls read in a loop, which results in surprisingly poor code + // generation for the common path where the buffer has enough bytes to fill the passed-in + // buffer. + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if self.buffer().len() >= buf.len() { + buf.copy_from_slice(&self.buffer()[..buf.len()]); + self.consume(buf.len()); + return Ok(()); + } + + crate::io::default_read_exact(self, buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { let total_len = bufs.iter().map(|b| b.len()).sum::<usize>(); if self.pos == self.cap && total_len >= self.buf.len() { |
