From 095bf01649a202b088c817bcdd3612d2604187e0 Mon Sep 17 00:00:00 2001 From: Han Mertens Date: Sun, 17 Jan 2021 17:49:02 +0100 Subject: [PATCH] Improve sift_down performance in BinaryHeap Because child > 0, the two statements are equivalent, but using saturating_sub and <= yields in faster code. This is most notable in the binary_heap::bench_into_sorted_vec benchmark, which shows a speedup of 1.26x, which uses sift_down_range internally. The speedup of pop (that uses sift_down_to_bottom internally) is much less significant as the sifting method is not called in a loop. --- library/alloc/src/collections/binary_heap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 33bd98d467cec..e025da74da471 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -565,7 +565,7 @@ impl BinaryHeap { let mut child = 2 * hole.pos() + 1; // Loop invariant: child == 2 * hole.pos() + 1. - while child < end - 1 { + while child <= end.saturating_sub(2) { // compare with the greater of the two children // SAFETY: child < end - 1 < self.len() and // child + 1 < end <= self.len(), so they're valid indexes. @@ -624,7 +624,7 @@ impl BinaryHeap { let mut child = 2 * hole.pos() + 1; // Loop invariant: child == 2 * hole.pos() + 1. - while child < end - 1 { + while child <= end.saturating_sub(2) { // SAFETY: child < end - 1 < self.len() and // child + 1 < end <= self.len(), so they're valid indexes. // child == 2 * hole.pos() + 1 != hole.pos() and