From 032804bf68e2ac13add895206f2173409acff836 Mon Sep 17 00:00:00 2001 From: Mikhail Zabaluev Date: Sun, 22 Feb 2015 19:20:18 +0200 Subject: [PATCH] In Vec::from_iter, unroll the first iteration For the first ever element to put into a vector, the branching conditions are more predictable. --- src/libcollections/vec.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index cb1199a59f60..3db55b82fe84 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1410,7 +1410,25 @@ impl ops::DerefMut for Vec { impl FromIterator for Vec { #[inline] fn from_iter>(iterable: I) -> Vec { - 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 }