Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 677e023

Browse files
authoredMar 20, 2025··
Use internal iteration in Vec::extend_desugared()
Because LLVM is unable to optimize well external iteration with some iterator kinds (e.g. `chain()`). To do that I had to hoist the `size_hint()` call to the beginning of the loop (since I no longer have access to the iterator inside the loop), which might slightly pessimize certain iterators that are able to give more accurate size bounds during iteration (e.g. `flatten()`). However, the effect should not be big, and also, common iterators like these also suffer from the external iteration optimizibility problem (e.g. `flatten()`).
1 parent 87e60a7 commit 677e023

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed
 

‎library/alloc/src/vec/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -3543,11 +3543,12 @@ impl<T, A: Allocator> Vec<T, A> {
35433543
// for item in iterator {
35443544
// self.push(item);
35453545
// }
3546-
while let Some(element) = iterator.next() {
3546+
let (lower, _) = iterator.size_hint();
3547+
let initial_len = self.len();
3548+
iterator.for_each(move |element| {
35473549
let len = self.len();
35483550
if len == self.capacity() {
3549-
let (lower, _) = iterator.size_hint();
3550-
self.reserve(lower.saturating_add(1));
3551+
self.reserve(lower.saturating_sub(len - initial_len).saturating_add(1));
35513552
}
35523553
unsafe {
35533554
ptr::write(self.as_mut_ptr().add(len), element);
@@ -3556,7 +3557,7 @@ impl<T, A: Allocator> Vec<T, A> {
35563557
// NB can't overflow since we would have had to alloc the address space
35573558
self.set_len(len + 1);
35583559
}
3559-
}
3560+
});
35603561
}
35613562

35623563
// specific extend for `TrustedLen` iterators, called both by the specializations

0 commit comments

Comments
 (0)
Please sign in to comment.