From cdf7d63bfce33d2390e3a0a27e01a07f262834e7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 11 Nov 2013 10:08:03 -0800 Subject: [PATCH] Optimize creation of buffered readers/writers 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. --- src/libstd/rt/io/buffered.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libstd/rt/io/buffered.rs b/src/libstd/rt/io/buffered.rs index fc6d43f551aa..8afb7183d77b 100644 --- a/src/libstd/rt/io/buffered.rs +++ b/src/libstd/rt/io/buffered.rs @@ -73,9 +73,17 @@ pub struct BufferedReader { impl BufferedReader { /// Creates a new `BufferedReader` with with the specified buffer capacity pub fn with_capacity(cap: uint, inner: R) -> BufferedReader { + // 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 { impl BufferedWriter { /// Creates a new `BufferedWriter` with with the specified buffer capacity pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter { + // 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 } }