Skip to content

Commit

Permalink
Select tiny sorts for 16-bit platforms
Browse files Browse the repository at this point in the history
Also skips stack alloc in stable sort if 16-bit target platform.
  • Loading branch information
Voultapher committed Sep 4, 2024
1 parent cd3d6e8 commit 670630d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 13 deletions.
31 changes: 19 additions & 12 deletions core/src/slice/sort/stable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,27 @@ pub fn sort<T, F: FnMut(&T, &T) -> bool, BufT: BufGuard<T>>(v: &mut [T], is_less
}

cfg_if! {
if #[cfg(feature = "optimize_for_size")] {
if #[cfg(any(feature = "optimize_for_size", target_pointer_width = "16"))] {
let alloc_len = len / 2;

// For small inputs 4KiB of stack storage suffices, which allows us to avoid
// calling the (de-)allocator. Benchmarks showed this was quite beneficial.
let mut stack_buf = AlignedStorage::<T, 4096>::new();
let stack_scratch = stack_buf.as_uninit_slice_mut();
let mut heap_buf;
let scratch = if stack_scratch.len() >= alloc_len {
stack_scratch
} else {
heap_buf = BufT::with_capacity(alloc_len);
heap_buf.as_uninit_slice_mut()
};
cfg_if! {
if #[cfg(target_pointer_width = "16")] {
let heap_buf = BufT::with_capacity(alloc_len);
let scratch = heap_buf.as_uninit_slice_mut();
} else {
// For small inputs 4KiB of stack storage suffices, which allows us to avoid
// calling the (de-)allocator. Benchmarks showed this was quite beneficial.
let mut stack_buf = AlignedStorage::<T, 4096>::new();
let stack_scratch = stack_buf.as_uninit_slice_mut();
let mut heap_buf;
let scratch = if stack_scratch.len() >= alloc_len {
stack_scratch
} else {
heap_buf = BufT::with_capacity(alloc_len);
heap_buf.as_uninit_slice_mut()
};
}
}

tiny::mergesort(v, scratch, is_less);
} else {
Expand Down
2 changes: 1 addition & 1 deletion core/src/slice/sort/unstable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn sort<T, F: FnMut(&T, &T) -> bool>(v: &mut [T], is_less: &mut F) {
}

cfg_if! {
if #[cfg(feature = "optimize_for_size")] {
if #[cfg(any(feature = "optimize_for_size", target_pointer_width = "16"))] {
heapsort::heapsort(v, is_less);
} else {
// More advanced sorting methods than insertion sort are faster if called in
Expand Down

0 comments on commit 670630d

Please sign in to comment.