You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auto merge of #68046 - Marwes:extend_for_each, r=<try>
perf: Use `for_each` in `Vec::extend`
`for_each` are specialized for iterators such as `chain` allowing for
faster iteration than a normal `for/while` loop.
Note that since this only checks `size_hint` once at the start it may
end up needing to call `reserve` more in the case that `size_hint`
returns a larger and more accurate lower bound during iteration.
This could maybe be alleviated with an implementation closure like the current
one but the extra complexity will likely end up harming the normal case
of an accurate or 0 (think `filter`) lower bound.
```rust
while let Some(element) = iterator.next() {
let (lower, _) = iterator.size_hint();
self.reserve(lower.saturating_add(1));
unsafe {
let len = self.len();
ptr::write(self.get_unchecked_mut(len), element);
// NB can't overflow since we would have had to alloc the address space
self.set_len(len + 1);
}
iterator.by_ref().take(self.capacity()).for_each(|element| {
unsafe {
let len = self.len();
ptr::write(self.get_unchecked_mut(len), element);
// NB can't overflow since we would have had to alloc the address space
self.set_len(len + 1);
}
});
}
// OR
let (lower, _) = iterator.size_hint();
self.reserve(lower);
loop {
let result = iterator.by_ref().try_for_each(|element| {
if self.len() == self.capacity() {
return Err(element);
}
unsafe {
let len = self.len();
ptr::write(self.get_unchecked_mut(len), element);
// NB can't overflow since we would have had to alloc the address space
self.set_len(len + 1);
}
Ok(())
});
match result {
Ok(()) => break,
Err(element) => {
let (lower, _) = iterator.size_hint();
self.reserve(lower.saturating_add(1));
self.push(element);
}
}
}
```
Closes#63340
0 commit comments