Skip to content

Commit ec8ae4b

Browse files
committed
Auto merge of #29811 - bluss:binary-heap-sift-less, r=gankro
BinaryHeap: Simplify sift down Sift down was doing all too much work: it can stop directly when the current element obeys the heap property in relation to its children. In the old code, sift down didn't compare the element to sift down at all, so it was maximally sifted down and relied on the sift up call to put it in the correct location. This should speed up heapify and .pop(). Also rename Hole::removed() to Hole::element()
2 parents b12a358 + 81fcdd4 commit ec8ae4b

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

src/libcollections/binary_heap.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -522,29 +522,30 @@ impl<T: Ord> BinaryHeap<T> {
522522

523523
while hole.pos() > start {
524524
let parent = (hole.pos() - 1) / 2;
525-
if hole.removed() <= hole.get(parent) { break }
525+
if hole.element() <= hole.get(parent) { break; }
526526
hole.move_to(parent);
527527
}
528528
}
529529
}
530530

531-
fn sift_down_range(&mut self, mut pos: usize, end: usize) {
532-
let start = pos;
531+
/// Take an element at `pos` and move it down the heap,
532+
/// while its children are larger.
533+
fn sift_down_range(&mut self, pos: usize, end: usize) {
533534
unsafe {
534535
let mut hole = Hole::new(&mut self.data, pos);
535536
let mut child = 2 * pos + 1;
536537
while child < end {
537538
let right = child + 1;
539+
// compare with the greater of the two children
538540
if right < end && !(hole.get(child) > hole.get(right)) {
539541
child = right;
540542
}
543+
// if we are already in order, stop.
544+
if hole.element() >= hole.get(child) { break; }
541545
hole.move_to(child);
542546
child = 2 * hole.pos() + 1;
543547
}
544-
545-
pos = hole.pos;
546548
}
547-
self.sift_up(start, pos);
548549
}
549550

550551
fn sift_down(&mut self, pos: usize) {
@@ -606,7 +607,7 @@ impl<'a, T> Hole<'a, T> {
606607

607608
/// Return a reference to the element removed
608609
#[inline(always)]
609-
fn removed(&self) -> &T {
610+
fn element(&self) -> &T {
610611
self.elt.as_ref().unwrap()
611612
}
612613

0 commit comments

Comments
 (0)