diff options
| author | bors <bors@rust-lang.org> | 2015-01-26 13:01:00 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-01-26 13:01:00 +0000 |
| commit | 977c44ade09450016d9c95dea245fd4464a509e9 (patch) | |
| tree | adea995c7831ebae76bca46e243cbd124f53626b /src | |
| parent | 59dcba5d14e5eada0a5e7eb0cad5efc7acd1d0e3 (diff) | |
| parent | c384ee18fcb55274682e8a9a24608bfc825bedce (diff) | |
| download | rust-977c44ade09450016d9c95dea245fd4464a509e9.tar.gz rust-977c44ade09450016d9c95dea245fd4464a509e9.zip | |
Auto merge of #21401 - kballard:optimize-shrink-to-fit, r=nikomatsakis
Don't reallocate when capacity is already equal to length
`Vec::shrink_to_fit()` may be called on vectors that are already the
correct length. Calling out to `reallocate()` in this case is a bad idea
because there is no guarantee that `reallocate()` won't allocate a new
buffer anyway, and based on performance seen in external benchmarks, it
seems likely that it is in fact reallocating a new buffer.
Before:
test string::tests::bench_exact_size_shrink_to_fit ... bench: 45 ns/iter (+/- 2)
After:
test string::tests::bench_exact_size_shrink_to_fit ... bench: 26 ns/iter (+/- 1)
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcollections/string.rs | 16 | ||||
| -rw-r--r-- | src/libcollections/vec.rs | 2 |
2 files changed, 17 insertions, 1 deletions
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index c965aedbc5d..562189370d6 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -1413,4 +1413,20 @@ mod tests { let _ = String::from_utf8_lossy(s.as_slice()); }); } + + #[bench] + fn bench_exact_size_shrink_to_fit(b: &mut Bencher) { + let s = "Hello there, the quick brown fox jumped over the lazy dog! \ + Lorem ipsum dolor sit amet, consectetur. "; + // ensure our operation produces an exact-size string before we benchmark it + let mut r = String::with_capacity(s.len()); + r.push_str(s); + assert_eq!(r.len(), r.capacity()); + b.iter(|| { + let mut r = String::with_capacity(s.len()); + r.push_str(s); + r.shrink_to_fit(); + r + }); + } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 52590297a6a..0de9b5733fb 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -356,7 +356,7 @@ impl<T> Vec<T> { } self.cap = 0; } - } else { + } else if self.cap != self.len { unsafe { // Overflow check is unnecessary as the vector is already at // least this large. |
