diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-11-11 10:08:03 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-11-11 10:08:03 -0800 |
| commit | cdf7d63bfce33d2390e3a0a27e01a07f262834e7 (patch) | |
| tree | beb67163fe1f02431c45b8d676d86ce6cd3bc18f /src | |
| parent | 4059b5c4b3b8a57a645982b0770d25f0283dfb06 (diff) | |
| download | rust-cdf7d63bfce33d2390e3a0a27e01a07f262834e7.tar.gz rust-cdf7d63bfce33d2390e3a0a27e01a07f262834e7.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libstd/rt/io/buffered.rs | 15 |
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 } } |
