@@ -1459,6 +1459,8 @@ impl<'a, T: 'a, A: Alloc> Vec<'a, T, A> {
14591459
14601460 /// Appends an element to the back of a vector.
14611461 ///
1462+ /// See also [`push_fast`].
1463+ ///
14621464 /// # Panics
14631465 ///
14641466 /// Panics if the number of elements in the vector overflows a `u32`.
@@ -1474,6 +1476,8 @@ impl<'a, T: 'a, A: Alloc> Vec<'a, T, A> {
14741476 /// vec.push(3);
14751477 /// assert_eq!(vec, [1, 2, 3]);
14761478 /// ```text
1479+ ///
1480+ /// [`push_fast`]: Self::push_fast
14771481 #[ inline]
14781482 pub fn push ( & mut self , value : T ) {
14791483 // This will panic or abort if we would allocate > isize::MAX bytes
@@ -1488,6 +1492,62 @@ impl<'a, T: 'a, A: Alloc> Vec<'a, T, A> {
14881492 }
14891493 }
14901494
1495+ /// Appends an element to the back of a vector, when it's likely that there's sufficient capacity.
1496+ ///
1497+ /// This method is equivalent to [`push`] except that it is optimized for the case where there's
1498+ /// capacity for at least one more element, without needing to grow.
1499+ ///
1500+ /// When you're dealing with a large `Vec` which grows infrequently, this method can be faster.
1501+ ///
1502+ /// # Panics
1503+ ///
1504+ /// Panics if the number of elements in the vector overflows a `u32`.
1505+ ///
1506+ /// # Examples
1507+ ///
1508+ /// ```text
1509+ /// use bumpalo::{Bump, collections::Vec};
1510+ ///
1511+ /// let b = Bump::new();
1512+ ///
1513+ /// let mut vec = Vec::from_iter_in([1, 2, 3], &b);
1514+ /// vec.pop();
1515+ /// vec.push_fast(4);
1516+ /// assert_eq!(vec, [1, 2, 4]);
1517+ /// ```text
1518+ ///
1519+ /// [`push`]: Self::push
1520+ #[ inline]
1521+ pub fn push_fast ( & mut self , value : T ) {
1522+ #[ expect( clippy:: if_not_else) ]
1523+ if self . len_u32 ( ) != self . capacity_u32 ( ) {
1524+ // Capacity for at least 1 more element. Write it.
1525+ unsafe {
1526+ let end = self . buf . ptr ( ) . add ( self . len_usize ( ) ) ;
1527+ ptr:: write ( end, value) ;
1528+ self . buf . increase_len ( 1 ) ;
1529+ }
1530+ } else {
1531+ // At capacity. Grow.
1532+ // This branch is rarely taken, so marked as `#[cold]` and `#[inline(never)]`.
1533+ #[ cold]
1534+ #[ inline( never) ]
1535+ fn push_slow < T , A : Alloc > ( v : & mut Vec < ' _ , T , A > , value : T ) {
1536+ // This will panic or abort if we would allocate > `isize::MAX` bytes
1537+ // or if the length increment would overflow for zero-sized types.
1538+ v. buf . grow_one ( ) ;
1539+
1540+ unsafe {
1541+ let end = v. buf . ptr ( ) . add ( v. len_usize ( ) ) ;
1542+ ptr:: write ( end, value) ;
1543+ v. buf . increase_len ( 1 ) ;
1544+ }
1545+ }
1546+
1547+ push_slow ( self , value) ;
1548+ }
1549+ }
1550+
14911551 /// Removes the last element from a vector and returns it, or [`None`] if it
14921552 /// is empty.
14931553 ///
0 commit comments