In Vec::from_iter, unroll the first iteration
For the first ever element to put into a vector, the branching conditions are more predictable.
This commit is contained in:
parent
a118b936fa
commit
032804bf68
1 changed files with 19 additions and 1 deletions
|
|
@ -1410,7 +1410,25 @@ impl<T> ops::DerefMut for Vec<T> {
|
|||
impl<T> FromIterator<T> for Vec<T> {
|
||||
#[inline]
|
||||
fn from_iter<I: IntoIterator<Item=T>>(iterable: I) -> Vec<T> {
|
||||
let mut vector = Vec::new();
|
||||
// Unroll the first iteration, as the vector is going to be
|
||||
// expanded on this iteration in every case when the iterable is not
|
||||
// empty, but the loop in extend_desugared() is not going to see the
|
||||
// vector being full in the few subsequent loop iterations.
|
||||
// So we get better branch prediction and the possibility to
|
||||
// construct the vector with initial estimated capacity.
|
||||
let mut iterator = iterable.into_iter();
|
||||
let mut vector = match iterator.next() {
|
||||
None => return Vec::new(),
|
||||
Some(element) => {
|
||||
let (lower, _) = iterator.size_hint();
|
||||
let mut vector = Vec::with_capacity(1 + lower);
|
||||
unsafe {
|
||||
ptr::write(vector.get_unchecked_mut(0), element);
|
||||
vector.set_len(1);
|
||||
}
|
||||
vector
|
||||
}
|
||||
};
|
||||
vector.extend(iterable);
|
||||
vector
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue