diff options
| author | Mikhail Zabaluev <mikhail.zabaluev@gmail.com> | 2015-02-22 19:20:18 +0200 |
|---|---|---|
| committer | Mikhail Zabaluev <mikhail.zabaluev@gmail.com> | 2015-02-22 20:42:35 +0200 |
| commit | 032804bf68e2ac13add895206f2173409acff836 (patch) | |
| tree | 7e6e6a43f39ac84311d376b1c051f42f8e2b7ffa /src | |
| parent | a118b936faa7f802c41214cb908622a7893bebfd (diff) | |
| download | rust-032804bf68e2ac13add895206f2173409acff836.tar.gz rust-032804bf68e2ac13add895206f2173409acff836.zip | |
In Vec::from_iter, unroll the first iteration
For the first ever element to put into a vector, the branching conditions are more predictable.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcollections/vec.rs | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index cb1199a59f6..3db55b82fe8 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -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 } |
