Skip to content

Commit 116bb4d

Browse files
committed
binary_heap: Unify Extend implementation.
Previously the bulk rebuild specialization was only available with Vec, and for general iterators Extend only provided pre-allocation through reserve(). By using a drop guard, we can safely bulk rebuild even if the iterator may panic. This allows benefiting from the bulk rebuild optimization without collecting iterator elements into a Vec beforehand, which would nullify any performance gains from bulk rebuild.
1 parent 11c589c commit 116bb4d

File tree

1 file changed

+2
-34
lines changed
  • library/alloc/src/collections/binary_heap

1 file changed

+2
-34
lines changed

library/alloc/src/collections/binary_heap/mod.rs

+2-34
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,6 @@ use crate::collections::TryReserveError;
154154
use crate::slice;
155155
use crate::vec::{self, AsVecIntoIter, Vec};
156156

157-
use super::SpecExtend;
158-
159157
#[cfg(test)]
160158
mod tests;
161159

@@ -1715,7 +1713,8 @@ impl<'a, T> IntoIterator for &'a BinaryHeap<T> {
17151713
impl<T: Ord> Extend<T> for BinaryHeap<T> {
17161714
#[inline]
17171715
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1718-
<Self as SpecExtend<I>>::spec_extend(self, iter);
1716+
let guard = RebuildOnDrop { rebuild_from: self.len(), heap: self };
1717+
guard.heap.data.extend(iter);
17191718
}
17201719

17211720
#[inline]
@@ -1729,37 +1728,6 @@ impl<T: Ord> Extend<T> for BinaryHeap<T> {
17291728
}
17301729
}
17311730

1732-
impl<T: Ord, I: IntoIterator<Item = T>> SpecExtend<I> for BinaryHeap<T> {
1733-
default fn spec_extend(&mut self, iter: I) {
1734-
self.extend_desugared(iter.into_iter());
1735-
}
1736-
}
1737-
1738-
impl<T: Ord> SpecExtend<Vec<T>> for BinaryHeap<T> {
1739-
fn spec_extend(&mut self, ref mut other: Vec<T>) {
1740-
let start = self.data.len();
1741-
self.data.append(other);
1742-
self.rebuild_tail(start);
1743-
}
1744-
}
1745-
1746-
impl<T: Ord> SpecExtend<BinaryHeap<T>> for BinaryHeap<T> {
1747-
fn spec_extend(&mut self, ref mut other: BinaryHeap<T>) {
1748-
self.append(other);
1749-
}
1750-
}
1751-
1752-
impl<T: Ord> BinaryHeap<T> {
1753-
fn extend_desugared<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1754-
let iterator = iter.into_iter();
1755-
let (lower, _) = iterator.size_hint();
1756-
1757-
self.reserve(lower);
1758-
1759-
iterator.for_each(move |elem| self.push(elem));
1760-
}
1761-
}
1762-
17631731
#[stable(feature = "extend_ref", since = "1.2.0")]
17641732
impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap<T> {
17651733
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {

0 commit comments

Comments
 (0)