Auto merge of #22200 - alexcrichton:opt-vec-collect, r=huonw
This PR is an optimization of the `FromIterator` implementation of `Vec` Benchmark: https://gist.github.com/alexcrichton/03d666159a28a80e7c70 Before: test macro_repeat1 ... bench: 57 ns/iter (+/- 1) test macro_repeat2 ... bench: 56 ns/iter (+/- 1) test map_clone1 ... bench: 828 ns/iter (+/- 13) test map_clone2 ... bench: 828 ns/iter (+/- 8) test repeat1 ... bench: 1104 ns/iter (+/- 10) test repeat2 ... bench: 1106 ns/iter (+/- 11) After: test macro_repeat1 ... bench: 75 ns/iter (+/- 21) test macro_repeat2 ... bench: 59 ns/iter (+/- 31) test map_clone1 ... bench: 34 ns/iter (+/- 22) test map_clone2 ... bench: 52 ns/iter (+/- 21) test repeat1 ... bench: 34 ns/iter (+/- 11) test repeat2 ... bench: 33 ns/iter (+/- 12) The idea behind this optimization is to avoid all bounds checks for space already allocated into the vector. This may involve running the iterator twice, but the first run of the iterator should be optimizable to a memcpy or memset if possible. The same treatment can in theory be applied to `Vec::extend` but the benchmarks for that currently get *worse* if the change is applied. This appears to be some LLVM optimizations going awry but it's seems prudent to land at least the `collect` portion beforehand.
This commit is contained in:
commit
b9ba643b72
1 changed files with 11 additions and 1 deletions
|
@ -1386,7 +1386,17 @@ impl<T> FromIterator<T> for Vec<T> {
|
|||
fn from_iter<I:Iterator<Item=T>>(iterator: I) -> Vec<T> {
|
||||
let (lower, _) = iterator.size_hint();
|
||||
let mut vector = Vec::with_capacity(lower);
|
||||
for element in iterator {
|
||||
|
||||
let mut i = iterator.fuse();
|
||||
for element in i.by_ref().take(vector.capacity()) {
|
||||
let len = vector.len();
|
||||
unsafe {
|
||||
ptr::write(vector.get_unchecked_mut(len), element);
|
||||
vector.set_len(len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
for element in i {
|
||||
vector.push(element)
|
||||
}
|
||||
vector
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue