diff options
| author | bors <bors@rust-lang.org> | 2013-11-11 19:31:14 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-11-11 19:31:14 -0800 |
| commit | 8b4683d79d4b74f53808470cd2f98b23a0af9b93 (patch) | |
| tree | a3383998a3d2db2ca06390936165af98d156dde0 /src | |
| parent | 86787f8befe0f8971f27bd15be1e16ec7aa99e7e (diff) | |
| parent | cdf7d63bfce33d2390e3a0a27e01a07f262834e7 (diff) | |
| download | rust-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.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 } } |
