about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorUlrik Sverdrup <bluss@users.noreply.github.com>2015-07-07 13:50:23 +0200
committerUlrik Sverdrup <bluss@users.noreply.github.com>2015-07-08 19:40:40 +0200
commit6ac0ba3c3a1fc20e17923724e1e7635131eb19d6 (patch)
tree24e01203766715d1e62275c80453cbc4acbf6974 /src/libstd
parent26f0cd5de7f71a0db0bb3857ce49a11cd0f7d876 (diff)
downloadrust-6ac0ba3c3a1fc20e17923724e1e7635131eb19d6.tar.gz
rust-6ac0ba3c3a1fc20e17923724e1e7635131eb19d6.zip
Improve Vec::resize so that it can be used in Read::read_to_end
We needed a more efficient way to zerofill the vector in read_to_end.
This to reduce the memory intialization overhead to a minimum.

Use the implementation of `std::vec::from_elem` (used for the vec![]
macro) for Vec::resize as well. For simple element types like u8, this
compiles to memset, so it makes Vec::resize much more efficient.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io/mod.rs12
-rw-r--r--src/libstd/lib.rs1
2 files changed, 11 insertions, 2 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 9021f32fad0..50c44299dc7 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -16,7 +16,7 @@ use cmp;
 use rustc_unicode::str as core_str;
 use error as std_error;
 use fmt;
-use iter::{self, Iterator, Extend};
+use iter::{Iterator};
 use marker::Sized;
 use ops::{Drop, FnOnce};
 use option::Option::{self, Some, None};
@@ -106,7 +106,7 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize>
             if new_write_size < DEFAULT_BUF_SIZE {
                 new_write_size *= 2;
             }
-            buf.extend(iter::repeat(0).take(new_write_size));
+            buf.resize(len + new_write_size, 0);
         }
 
         match r.read(&mut buf[len..]) {
@@ -984,6 +984,14 @@ mod tests {
         let mut v = Vec::new();
         assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
         assert_eq!(v, b"1");
+
+        let cap = 1024 * 1024;
+        let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
+        let mut v = Vec::new();
+        let (a, b) = data.split_at(data.len() / 2);
+        assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len());
+        assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len());
+        assert_eq!(v, data);
     }
 
     #[test]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 73e45619774..caf3f497e10 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -146,6 +146,7 @@
 #![feature(unique)]
 #![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(vec_push_all)]
+#![feature(vec_resize)]
 #![feature(wrapping)]
 #![feature(zero_one)]
 #![cfg_attr(windows, feature(str_utf16))]