From b5ed39ff10f0e46be6e97b577477e0f60234fa0b Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 1 Aug 2018 10:23:07 +0200 Subject: [PATCH] Implement custom read_to_end for io::Take --- src/libstd/io/mod.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 5e89ad45f81d2..b83f3fbe7a59c 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -354,19 +354,26 @@ fn append_to_string(buf: &mut String, f: F) -> Result // avoid paying to allocate and zero a huge chunk of memory if the reader only // has 4 bytes while still making large reads if the reader does have a ton // of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every -// time is 4,500 times (!) slower than this if the reader has a very small -// amount of data to return. +// time is 4,500 times (!) slower than a default reservation size of 32 if the +// reader has a very small amount of data to return. // // Because we're extending the buffer with uninitialized data for trusted // readers, we need to make sure to truncate that if any of this panics. fn read_to_end(r: &mut R, buf: &mut Vec) -> Result { + read_to_end_with_reservation(r, buf, 32) +} + +fn read_to_end_with_reservation(r: &mut R, + buf: &mut Vec, + reservation_size: usize) -> Result +{ let start_len = buf.len(); let mut g = Guard { len: buf.len(), buf: buf }; let ret; loop { if g.len == g.buf.len() { unsafe { - g.buf.reserve(32); + g.buf.reserve(reservation_size); let capacity = g.buf.capacity(); g.buf.set_len(capacity); r.initializer().initialize(&mut g.buf[g.len..]); @@ -1899,6 +1906,12 @@ impl Read for Take { unsafe fn initializer(&self) -> Initializer { self.inner.initializer() } + + fn read_to_end(&mut self, buf: &mut Vec) -> Result { + let reservation_size = cmp::min(self.limit, 32) as usize; + + read_to_end_with_reservation(self, buf, reservation_size) + } } #[stable(feature = "rust1", since = "1.0.0")]