about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-11-11 19:31:14 -0800
committerbors <bors@rust-lang.org>2013-11-11 19:31:14 -0800
commit8b4683d79d4b74f53808470cd2f98b23a0af9b93 (patch)
treea3383998a3d2db2ca06390936165af98d156dde0 /src
parent86787f8befe0f8971f27bd15be1e16ec7aa99e7e (diff)
parentcdf7d63bfce33d2390e3a0a27e01a07f262834e7 (diff)
downloadrust-8b4683d79d4b74f53808470cd2f98b23a0af9b93.tar.gz
rust-8b4683d79d4b74f53808470cd2f98b23a0af9b93.zip
auto merge of #10424 : alexcrichton/rust/optimize-buffered, r=brson
I was benchmarking rust-http recently, and I saw that 50% of its time was spent
creating buffered readers/writers. Albeit rust-http wasn't using
std::rt::io::buffered, but the same idea applies here. It's much cheaper to
malloc a large region and not initialize it than to set it all to 0. Buffered
readers/writers never use uninitialized data, and their internal buffers are
encapsulated, so any usage of uninitialized slots are an implementation bug in
the readers/writers.
Diffstat (limited to 'src')
-rw-r--r--src/libstd/rt/io/buffered.rs15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/libstd/rt/io/buffered.rs b/src/libstd/rt/io/buffered.rs
index fc6d43f551a..8afb7183d77 100644
--- a/src/libstd/rt/io/buffered.rs
+++ b/src/libstd/rt/io/buffered.rs
@@ -73,9 +73,17 @@ pub struct BufferedReader<R> {
 impl<R: Reader> BufferedReader<R> {
     /// Creates a new `BufferedReader` with with the specified buffer capacity
     pub fn with_capacity(cap: uint, inner: R) -> BufferedReader<R> {
+        // It's *much* faster to create an uninitialized buffer than it is to
+        // fill everything in with 0. This buffer is entirely an implementation
+        // detail and is never exposed, so we're safe to not initialize
+        // everything up-front. This allows creation of BufferedReader instances
+        // to be very cheap (large mallocs are not nearly as expensive as large
+        // callocs).
+        let mut buf = vec::with_capacity(cap);
+        unsafe { vec::raw::set_len(&mut buf, cap); }
         BufferedReader {
             inner: inner,
-            buf: vec::from_elem(cap, 0u8),
+            buf: buf,
             pos: 0,
             cap: 0
         }
@@ -183,9 +191,12 @@ pub struct BufferedWriter<W> {
 impl<W: Writer> BufferedWriter<W> {
     /// Creates a new `BufferedWriter` with with the specified buffer capacity
     pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter<W> {
+        // See comments in BufferedReader for why this uses unsafe code.
+        let mut buf = vec::with_capacity(cap);
+        unsafe { vec::raw::set_len(&mut buf, cap); }
         BufferedWriter {
             inner: inner,
-            buf: vec::from_elem(cap, 0u8),
+            buf: buf,
             pos: 0
         }
     }