From 6dfcf9afde98b4e873bfb0012e2efa0f058cc19d Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sat, 7 Nov 2020 20:01:47 +0100 Subject: [PATCH 1/4] Remove branches from sift_down_to_bottom loop --- library/alloc/src/collections/binary_heap.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index b67c72d7136..10ed99b2943 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -563,15 +563,14 @@ impl BinaryHeap { unsafe { let mut hole = Hole::new(&mut self.data, pos); let mut child = 2 * pos + 1; - while child < end { - let right = child + 1; - // compare with the greater of the two children - if right < end && hole.get(child) <= hole.get(right) { - child = right; - } + while child < end - 1 { + child += (hole.get(child) <= hole.get(child + 1)) as usize; hole.move_to(child); child = 2 * hole.pos() + 1; } + if child == end - 1 { + hole.move_to(child); + } pos = hole.pos; } self.sift_up(start, pos); From 25b3f61c3821fd597961f9dd394482b71600e859 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sat, 7 Nov 2020 21:27:30 +0100 Subject: [PATCH 2/4] Remove useless branches from sift_down_range loop --- library/alloc/src/collections/binary_heap.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 10ed99b2943..2d68146249b 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -531,19 +531,19 @@ impl BinaryHeap { unsafe { let mut hole = Hole::new(&mut self.data, pos); let mut child = 2 * pos + 1; - while child < end { - let right = child + 1; + while child < end - 1 { // compare with the greater of the two children - if right < end && hole.get(child) <= hole.get(right) { - child = right; - } + child += (hole.get(child) <= hole.get(child + 1)) as usize; // if we are already in order, stop. if hole.element() >= hole.get(child) { - break; + return; } hole.move_to(child); child = 2 * hole.pos() + 1; } + if child == end - 1 && hole.element() < hole.get(child) { + hole.move_to(child); + } } } From 8d1575365dd9c3260d0aa44203b9ad169f0b5d74 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sat, 7 Nov 2020 21:43:47 +0100 Subject: [PATCH 3/4] Remove useless bound checks from into_sorted_vec --- library/alloc/src/collections/binary_heap.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 2d68146249b..17f0668c0ea 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -495,7 +495,10 @@ impl BinaryHeap { let mut end = self.len(); while end > 1 { end -= 1; - self.data.swap(0, end); + unsafe { + let ptr = self.data.as_mut_ptr(); + ptr::swap(ptr, ptr.add(end)); + } self.sift_down_range(0, end); } self.into_vec() From 387568cd564317ca7491e6960ddcbe13beecae13 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Mon, 9 Nov 2020 22:34:31 +0100 Subject: [PATCH 4/4] Added SAFETY comment as request --- library/alloc/src/collections/binary_heap.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 17f0668c0ea..97ebc12175f 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -495,6 +495,10 @@ impl BinaryHeap { let mut end = self.len(); while end > 1 { end -= 1; + // SAFETY: `end` goes from `self.len() - 1` to 1 (both included), + // so it's always a valid index to access. + // It is safe to access index 0 (i.e. `ptr`), because + // 1 <= end < self.len(), which means self.len() >= 2. unsafe { let ptr = self.data.as_mut_ptr(); ptr::swap(ptr, ptr.add(end));