Skip to content

Commit

Permalink
Add eager transition (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
Voultapher authored Feb 22, 2024
1 parent 4ec8b85 commit 4a42c29
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
26 changes: 12 additions & 14 deletions src/drift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,18 @@ pub fn sort<T, F: FnMut(&T, &T) -> bool>(
}
let scale_factor = merge_tree_scale_factor(len);

// It's important to have a relatively high entry barrier for pre-sorted
// runs, as the presence of a single such run will force on average several
// merge operations and shrink the maximum quicksort size a lot. For that
// reason we use sqrt(len) as our pre-sorted run threshold, but no smaller
// than 32. When eagerly sorting we use crate::quicksort::SMALL_SORT_THRESHOLD
// as our threshold, as we will call small_sort on any runs smaller than this.
const MIN_MERGE_SLICE_LEN: usize = 32;
let min_good_run_len = if eager_sort {
T::SMALL_SORT_THRESHOLD
} else if len <= (MIN_MERGE_SLICE_LEN * MIN_MERGE_SLICE_LEN) {
MIN_MERGE_SLICE_LEN
} else {
sqrt_approx(len)
};
// It's important to have a relatively high entry barrier for pre-sorted runs, as the presence
// of a single such run will force on average several merge operations and shrink the maximum
// quicksort size a lot. For that reason we use sqrt(len) as our pre-sorted run threshold, with
// SMALL_SORT_THRESHOLD as the lower limit. When eagerly sorting we also use
// SMALL_SORT_THRESHOLD as our threshold, as we will call small_sort on any runs smaller than
// this.
let min_good_run_len =
if eager_sort || len <= (T::SMALL_SORT_THRESHOLD * T::SMALL_SORT_THRESHOLD) {
T::SMALL_SORT_THRESHOLD
} else {
sqrt_approx(len)
};

// (stack_len, runs, desired_depths) together form a stack maintaining run
// information for the powersort heuristic. desired_depths[i] is the desired
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ fn driftsort_main<T, F: FnMut(&T, &T) -> bool, BufT: BufGuard<T>>(v: &mut [T], i
let scratch_slice =
unsafe { slice::from_raw_parts_mut(buf.mut_ptr() as *mut MaybeUninit<T>, buf.capacity()) };

let eager_sort = false;
// Using the hybrid quick + merge-sort has performance issues with the transition from insertion
// sort to main loop. A more gradual and smoother transition can be had by using an always eager
// merge approach as long as it can be served by a single merge.
use crate::smallsort::SmallSortTypeImpl;
let eager_sort = len <= T::SMALL_SORT_THRESHOLD * 2;
drift::sort(v, scratch_slice, eager_sort, is_less);
}

Expand Down

0 comments on commit 4a42c29

Please sign in to comment.