Skip to content

Commit dbe1d24

Browse files
Voultapherorlp
authored andcommitted
Fix nearly sorted rejection for small inputs
1 parent 6c30f85 commit dbe1d24

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

src/drift.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use core::intrinsics;
33
use core::mem::MaybeUninit;
44

55
use crate::merge::merge;
6-
use crate::smallsort::SmallSortTypeImpl;
76

87
pub fn sort<T, F: FnMut(&T, &T) -> bool>(
98
v: &mut [T],
@@ -19,16 +18,16 @@ pub fn sort<T, F: FnMut(&T, &T) -> bool>(
1918

2019
// It's important to have a relatively high entry barrier for pre-sorted runs, as the presence
2120
// of a single such run will force on average several merge operations and shrink the maximum
22-
// quicksort size a lot. For that reason we use sqrt(len) as our pre-sorted run threshold, with
23-
// SMALL_SORT_THRESHOLD as the lower limit. When eagerly sorting we also use
24-
// SMALL_SORT_THRESHOLD as our threshold, as we will call small_sort on any runs smaller than
25-
// this.
26-
let min_good_run_len =
27-
if eager_sort || len <= (T::SMALL_SORT_THRESHOLD * T::SMALL_SORT_THRESHOLD) {
28-
T::SMALL_SORT_THRESHOLD
29-
} else {
30-
sqrt_approx(len)
31-
};
21+
// quicksort size a lot. For that reason we use sqrt(len) as our pre-sorted run threshold.
22+
const MIN_SQRT_RUN_LEN: usize = 64;
23+
24+
let min_good_run_len = if len <= (MIN_SQRT_RUN_LEN * MIN_SQRT_RUN_LEN) {
25+
// For small input length `MIN_SQRT_RUN_LEN` would break pattern detection of full or nearly
26+
// sorted inputs.
27+
cmp::min(len - len / 2, MIN_SQRT_RUN_LEN)
28+
} else {
29+
sqrt_approx(len)
30+
};
3231

3332
// (stack_len, runs, desired_depths) together form a stack maintaining run
3433
// information for the powersort heuristic. desired_depths[i] is the desired
@@ -221,6 +220,8 @@ fn create_run<T, F: FnMut(&T, &T) -> bool>(
221220
eager_sort: bool,
222221
is_less: &mut F,
223222
) -> DriftsortRun {
223+
use crate::smallsort::SmallSortTypeImpl;
224+
224225
let (run_len, was_reversed) = find_existing_run(v, is_less);
225226

226227
let len = v.len();

0 commit comments

Comments
 (0)