about summary refs log tree commit diff
path: root/library/std/src/io/buffered
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2023-10-13 08:26:49 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2023-10-20 08:52:56 +1100
commit181ce631832b066febd966043f0accea91fb66d4 (patch)
tree8c6d3020f5479be8806055574637ff02535cfe0e /library/std/src/io/buffered
parentcc705b801236d064260bb67b3a0a25e4747fa7ec (diff)
Specialize `Bytes<R>::next` when `R` is a `BufReader`.
This reduces the runtime for a simple program using `Bytes::next` to
iterate through a file from 220ms to 70ms on my Linux box.
Diffstat (limited to 'library/std/src/io/buffered')
-rw-r--r--library/std/src/io/buffered/bufreader.rs25
1 files changed, 20 insertions, 5 deletions
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 7097dfef88d..55aafc3db33 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -2,7 +2,8 @@ mod buffer;
 
 use crate::fmt;
 use crate::io::{
-    self, BorrowedCursor, BufRead, IoSliceMut, Read, Seek, SeekFrom, SizeHint, DEFAULT_BUF_SIZE,
+    self, uninlined_slow_read_byte, BorrowedCursor, BufRead, IoSliceMut, Read, Seek, SeekFrom,
+    SizeHint, SpecReadByte, DEFAULT_BUF_SIZE,
 };
 use buffer::Buffer;
 
@@ -259,6 +260,22 @@ impl<R: ?Sized + Seek> BufReader<R> {
     }
 }
 
+impl<R> SpecReadByte for BufReader<R>
+where
+    Self: Read,
+{
+    #[inline]
+    fn spec_read_byte(&mut self) -> Option<io::Result<u8>> {
+        let mut byte = 0;
+        if self.buf.consume_with(1, |claimed| byte = claimed[0]) {
+            return Some(Ok(byte));
+        }
+
+        // Fallback case, only reached once per buffer refill.
+        uninlined_slow_read_byte(self)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<R: ?Sized + Read> Read for BufReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
@@ -269,10 +286,8 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
             self.discard_buffer();
             return self.inner.read(buf);
         }
-        let nread = {
-            let mut rem = self.fill_buf()?;
-            rem.read(buf)?
-        };
+        let mut rem = self.fill_buf()?;
+        let nread = rem.read(buf)?;
         self.consume(nread);
         Ok(nread)
     }