Skip to content

Commit

Permalink
Auto merge of rust-lang#117179 - Voultapher:fix-useless-comp-in-parti…
Browse files Browse the repository at this point in the history
…tion-equal, r=Mark-Simulacrum

Avoid unnecessary comparison in partition_equal

The branchy Hoare partition `partition_equal` as part of `slice::sort_unstable` has a bug that makes it perform a comparison of the last element twice.

Measuring inputs with a Zipfian distribution with characterizing exponent s == 1.0, yields a ~0.05% reduction in the total number of comparisons performed.
  • Loading branch information
bors committed Nov 5, 2023
2 parents 6c7de31 + e501add commit 5103173
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions library/core/src/slice/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,9 +628,14 @@ where
let _pivot_guard = InsertionHole { src: &*tmp, dest: pivot };
let pivot = &*tmp;

let len = v.len();
if len == 0 {
return 0;
}

// Now partition the slice.
let mut l = 0;
let mut r = v.len();
let mut r = len;
loop {
// SAFETY: The unsafety below involves indexing an array.
// For the first one: We already do the bounds checking here with `l < r`.
Expand All @@ -643,8 +648,11 @@ where
}

// Find the last element equal to the pivot.
while l < r && is_less(pivot, v.get_unchecked(r - 1)) {
loop {
r -= 1;
if l >= r || !is_less(pivot, v.get_unchecked(r)) {
break;
}
}

// Are we done?
Expand All @@ -653,7 +661,6 @@ where
}

// Swap the found pair of out-of-order elements.
r -= 1;
let ptr = v.as_mut_ptr();
ptr::swap(ptr.add(l), ptr.add(r));
l += 1;
Expand Down

0 comments on commit 5103173

Please sign in to comment.