@@ -1469,42 +1469,26 @@ impl<T> ops::DerefMut for Vec<T> {
1469
1469
impl < T > FromIterator < T > for Vec < T > {
1470
1470
#[ inline]
1471
1471
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.
1472
1478
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
1506
1489
}
1507
- }
1490
+ } ;
1491
+ vector. extend_desugared ( iterator) ;
1508
1492
vector
1509
1493
}
1510
1494
}
@@ -1569,11 +1553,27 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
1569
1553
impl < T > Extend < T > for Vec < T > {
1570
1554
#[ inline]
1571
1555
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
+ }
1577
1577
}
1578
1578
}
1579
1579
}
0 commit comments