Skip to content

Add optimize_for_size variants for stable and unstable sort as well as select_nth_unstable #129587

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 24, 2024
Prev Previous commit
Next Next commit
Drop bubble_sort
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
commit f2d4198d6ef65134fe5bc277e362df90d237a41d
1 change: 0 additions & 1 deletion library/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 library/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 library/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
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy