Skip to content

Commit

Permalink
Drop bubble_sort
Browse files Browse the repository at this point in the history
While using it results in slightly slammer binaries, it's not deemed
worth it to add yet another sort algorithm to the standard library.
select_nth_unstable has bigger binary-size problems.
  • Loading branch information
Voultapher committed Sep 4, 2024
1 parent 717e3aa commit bea61da
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 41 deletions.
1 change: 0 additions & 1 deletion core/src/slice/sort/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ pub mod stable;
pub mod unstable;

pub(crate) mod select;
#[cfg(not(feature = "optimize_for_size"))]
pub(crate) mod shared;
41 changes: 1 addition & 40 deletions core/src/slice/sort/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use crate::mem::{self, SizedTypeProperties};
#[cfg(not(feature = "optimize_for_size"))]
use crate::slice::sort::shared::pivot::choose_pivot;
#[cfg(not(feature = "optimize_for_size"))]
use crate::slice::sort::shared::smallsort::insertion_sort_shift_left;
use crate::slice::sort::unstable::quicksort::partition;

Expand Down Expand Up @@ -176,13 +175,7 @@ fn median_of_medians<T, F: FnMut(&T, &T) -> bool>(mut v: &mut [T], is_less: &mut
loop {
if v.len() <= INSERTION_SORT_THRESHOLD {
if v.len() >= 2 {
cfg_if! {
if #[cfg(feature = "optimize_for_size")] {
bubble_sort(v, is_less);
} else {
insertion_sort_shift_left(v, 1, is_less);
}
}
insertion_sort_shift_left(v, 1, is_less);
}

return;
Expand Down Expand Up @@ -314,35 +307,3 @@ fn median_idx<T, F: FnMut(&T, &T) -> bool>(
}
b
}

// It's possible to re-use the insertion sort in the smallsort module, but with optimize_for_size it
// would clutter that module with cfg statements and make it generally harder to read and develop.
// So to decouple things and simplify it, we use an even smaller bubble sort.
#[cfg(feature = "optimize_for_size")]
fn bubble_sort<T, F: FnMut(&T, &T) -> bool>(v: &mut [T], is_less: &mut F) {
use crate::ptr;

let mut n = v.len();

let v_base = v.as_mut_ptr();

while n > 1 {
let loop_n = n;
n = 0;
for i in 1..loop_n {
// SAFETY: The loop construction implies that `i` and `i - 1` will always be in-bounds.
unsafe {
// Even if `is_less` erroneously always returns true, we are guaranteed that `n`
// reduces by one each out loop iteration, because `1..n` is exclusive. This
// guarantees a bounded run-time should `Ord` be implemented incorrectly.
let v_i = v_base.add(i);
let v_i_minus_one = v_base.add(i - 1);

if is_less(&*v_i, &*v_i_minus_one) {
ptr::swap_nonoverlapping(v_i, v_i_minus_one, 1);
n = i;
}
}
}
}
}
2 changes: 2 additions & 0 deletions core/src/slice/sort/shared/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg_attr(feature = "optimize_for_size", allow(dead_code))]

use crate::marker::Freeze;

pub(crate) mod pivot;
Expand Down

0 comments on commit bea61da

Please sign in to comment.