From 116bb4dfb21085ec8e6c45551cc69ff59a3598cd Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sat, 25 Feb 2023 17:03:03 +0900 Subject: [PATCH] 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. --- .../alloc/src/collections/binary_heap/mod.rs | 36 ++----------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index b6cb7913d90..7c8cdf6ee3b 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -154,8 +154,6 @@ use crate::collections::TryReserveError; use crate::slice; use crate::vec::{self, AsVecIntoIter, Vec}; -use super::SpecExtend; - #[cfg(test)] mod tests; @@ -1715,7 +1713,8 @@ impl<'a, T> IntoIterator for &'a BinaryHeap { impl Extend for BinaryHeap { #[inline] fn extend>(&mut self, iter: I) { - >::spec_extend(self, iter); + let guard = RebuildOnDrop { rebuild_from: self.len(), heap: self }; + guard.heap.data.extend(iter); } #[inline] @@ -1729,37 +1728,6 @@ impl Extend for BinaryHeap { } } -impl> SpecExtend for BinaryHeap { - default fn spec_extend(&mut self, iter: I) { - self.extend_desugared(iter.into_iter()); - } -} - -impl SpecExtend> for BinaryHeap { - fn spec_extend(&mut self, ref mut other: Vec) { - let start = self.data.len(); - self.data.append(other); - self.rebuild_tail(start); - } -} - -impl SpecExtend> for BinaryHeap { - fn spec_extend(&mut self, ref mut other: BinaryHeap) { - self.append(other); - } -} - -impl BinaryHeap { - fn extend_desugared>(&mut self, iter: I) { - let iterator = iter.into_iter(); - let (lower, _) = iterator.size_hint(); - - self.reserve(lower); - - iterator.for_each(move |elem| self.push(elem)); - } -} - #[stable(feature = "extend_ref", since = "1.2.0")] impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap { fn extend>(&mut self, iter: I) {