about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMikhail Zabaluev <mikhail.zabaluev@gmail.com>2015-02-22 19:20:18 +0200
committerMikhail Zabaluev <mikhail.zabaluev@gmail.com>2015-02-22 20:42:35 +0200
commit032804bf68e2ac13add895206f2173409acff836 (patch)
tree7e6e6a43f39ac84311d376b1c051f42f8e2b7ffa /src
parenta118b936faa7f802c41214cb908622a7893bebfd (diff)
downloadrust-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.rs20
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
     }