Skip to content

Commit 032804b

Browse files
committed
In Vec::from_iter, unroll the first iteration
For the first ever element to put into a vector, the branching conditions are more predictable.
1 parent a118b93 commit 032804b

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/libcollections/vec.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1410,7 +1410,25 @@ impl<T> ops::DerefMut for Vec<T> {
14101410
impl<T> FromIterator<T> for Vec<T> {
14111411
#[inline]
14121412
fn from_iter<I: IntoIterator<Item=T>>(iterable: I) -> Vec<T> {
1413-
let mut vector = Vec::new();
1413+
// Unroll the first iteration, as the vector is going to be
1414+
// expanded on this iteration in every case when the iterable is not
1415+
// empty, but the loop in extend_desugared() is not going to see the
1416+
// vector being full in the few subsequent loop iterations.
1417+
// So we get better branch prediction and the possibility to
1418+
// construct the vector with initial estimated capacity.
1419+
let mut iterator = iterable.into_iter();
1420+
let mut vector = match iterator.next() {
1421+
None => return Vec::new(),
1422+
Some(element) => {
1423+
let (lower, _) = iterator.size_hint();
1424+
let mut vector = Vec::with_capacity(1 + lower);
1425+
unsafe {
1426+
ptr::write(vector.get_unchecked_mut(0), element);
1427+
vector.set_len(1);
1428+
}
1429+
vector
1430+
}
1431+
};
14141432
vector.extend(iterable);
14151433
vector
14161434
}

0 commit comments

Comments
 (0)