about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMikhail Zabaluev <mikhail.zabaluev@gmail.com>2020-11-22 17:00:48 +0200
committerMikhail Zabaluev <mikhail.zabaluev@gmail.com>2020-11-22 17:05:14 +0200
commit674dd623ee067d4298fda867f72442b13014eaa3 (patch)
treeecbbe148aa0707d6032e81c4ec48b2162cda0a54
parent00deeb35c8149508240549f5c9f3908a7ba9ee11 (diff)
downloadrust-674dd623ee067d4298fda867f72442b13014eaa3.tar.gz
rust-674dd623ee067d4298fda867f72442b13014eaa3.zip
Reduce branching in write_vectored for BufWriter
Do what write does and optimize for the most likely case:
slices are much smaller than the buffer. If a slice does not fit
completely in the remaining capacity of the buffer, it is left out
rather than buffered partially. Special treatment is only left for
oversized slices that are written directly to the underlying writer.
-rw-r--r--library/std/src/io/buffered/bufwriter.rs23
1 files changed, 9 insertions, 14 deletions
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index e42fa4297ef..3b3399860ba 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -343,9 +343,8 @@ impl<W: Write> Write for BufWriter<W> {
                 Ok(total_len)
             }
         } else {
-            let mut total_written = 0;
             let mut iter = bufs.iter();
-            if let Some(buf) = iter.by_ref().find(|&buf| !buf.is_empty()) {
+            let mut total_written = if let Some(buf) = iter.by_ref().find(|&buf| !buf.is_empty()) {
                 // This is the first non-empty slice to write, so if it does
                 // not fit in the buffer, we still get to flush and proceed.
                 if self.buf.len() + buf.len() > self.buf.capacity() {
@@ -360,22 +359,18 @@ impl<W: Write> Write for BufWriter<W> {
                     return r;
                 } else {
                     self.buf.extend_from_slice(buf);
-                    total_written += buf.len();
+                    buf.len()
                 }
-                debug_assert!(total_written != 0);
-            }
+            } else {
+                return Ok(0);
+            };
+            debug_assert!(total_written != 0);
             for buf in iter {
-                if buf.len() >= self.buf.capacity() {
-                    // This slice should be written directly, but we have
-                    // already buffered some of the input. Bail out,
-                    // expecting it to be handled as the first slice in the
-                    // next call to write_vectored.
+                if self.buf.len() + buf.len() > self.buf.capacity() {
                     break;
                 } else {
-                    total_written += self.write_to_buf(buf);
-                    if self.buf.capacity() == self.buf.len() {
-                        break;
-                    }
+                    self.buf.extend_from_slice(buf);
+                    total_written += buf.len();
                 }
             }
             Ok(total_written)