@@ -1469,42 +1469,26 @@ impl<T> ops::DerefMut for Vec<T> {
14691469impl < T > FromIterator < T > for Vec < T > {
14701470 #[ inline]
14711471 fn from_iter < I : IntoIterator < Item =T > > ( iterable : I ) -> Vec < T > {
1472+ // Unroll the first iteration, as the vector is going to be
1473+ // expanded on this iteration in every case when the iterable is not
1474+ // empty, but the loop in extend_desugared() is not going to see the
1475+ // vector being full in the few subsequent loop iterations.
1476+ // So we get better branch prediction and the possibility to
1477+ // construct the vector with initial estimated capacity.
14721478 let mut iterator = iterable. into_iter ( ) ;
1473- let ( lower, _) = iterator. size_hint ( ) ;
1474- let mut vector = Vec :: with_capacity ( lower) ;
1475-
1476- // This function should be the moral equivalent of:
1477- //
1478- // for item in iterator {
1479- // vector.push(item);
1480- // }
1481- //
1482- // This equivalent crucially runs the iterator precisely once. Below we
1483- // actually in theory run the iterator twice (one without bounds checks
1484- // and one with). To achieve the "moral equivalent", we use the `if`
1485- // statement below to break out early.
1486- //
1487- // If the first loop has terminated, then we have one of two conditions.
1488- //
1489- // 1. The underlying iterator returned `None`. In this case we are
1490- // guaranteed that less than `vector.capacity()` elements have been
1491- // returned, so we break out early.
1492- // 2. The underlying iterator yielded `vector.capacity()` elements and
1493- // has not yielded `None` yet. In this case we run the iterator to
1494- // its end below.
1495- for element in iterator. by_ref ( ) . take ( vector. capacity ( ) ) {
1496- let len = vector. len ( ) ;
1497- unsafe {
1498- ptr:: write ( vector. get_unchecked_mut ( len) , element) ;
1499- vector. set_len ( len + 1 ) ;
1500- }
1501- }
1502-
1503- if vector. len ( ) == vector. capacity ( ) {
1504- for element in iterator {
1505- vector. push ( element) ;
1479+ let mut vector = match iterator. next ( ) {
1480+ None => return Vec :: new ( ) ,
1481+ Some ( element) => {
1482+ let ( lower, _) = iterator. size_hint ( ) ;
1483+ let mut vector = Vec :: with_capacity ( 1 + lower) ;
1484+ unsafe {
1485+ ptr:: write ( vector. get_unchecked_mut ( 0 ) , element) ;
1486+ vector. set_len ( 1 ) ;
1487+ }
1488+ vector
15061489 }
1507- }
1490+ } ;
1491+ vector. extend_desugared ( iterator) ;
15081492 vector
15091493 }
15101494}
@@ -1569,11 +1553,27 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
15691553impl < T > Extend < T > for Vec < T > {
15701554 #[ inline]
15711555 fn extend < I : IntoIterator < Item =T > > ( & mut self , iterable : I ) {
1572- let iterator = iterable. into_iter ( ) ;
1573- let ( lower, _) = iterator. size_hint ( ) ;
1574- self . reserve ( lower) ;
1575- for element in iterator {
1576- self . push ( element)
1556+ self . extend_desugared ( iterable. into_iter ( ) )
1557+ }
1558+ }
1559+
1560+ impl < T > Vec < T > {
1561+ fn extend_desugared < I : Iterator < Item =T > > ( & mut self , mut iterator : I ) {
1562+ // This function should be the moral equivalent of:
1563+ //
1564+ // for item in iterator {
1565+ // self.push(item);
1566+ // }
1567+ while let Some ( element) = iterator. next ( ) {
1568+ let len = self . len ( ) ;
1569+ if len == self . capacity ( ) {
1570+ let ( lower, _) = iterator. size_hint ( ) ;
1571+ self . reserve ( lower + 1 ) ;
1572+ }
1573+ unsafe {
1574+ ptr:: write ( self . get_unchecked_mut ( len) , element) ;
1575+ self . set_len ( len + 1 ) ;
1576+ }
15771577 }
15781578 }
15791579}
0 commit comments