@@ -63,19 +63,31 @@ where
63
63
F : FnMut ( & T , & T ) -> bool ,
64
64
{
65
65
let len = v. len ( ) ;
66
- let ( run_len, was_reversed) = find_existing_run ( v, is_less) ;
66
+ let check_existing_run = ' cer: {
67
+ let v = & v[ ..] ;
68
+ // Skip `find_existing_run` if head and tail sorted in different orders
69
+ // because we are interested only if the whole slice is sorted.
70
+ // This should skip running `find_existing_run` for an almost whole slice
71
+ // in cases when user tries to sort a vector after single call to push.
72
+ let [ h0, h1, ..] = v else { break ' cer true } ;
73
+ let [ .., t0, t1] = v else { break ' cer true } ;
74
+ ( is_less ( h0, h1) && !is_less ( t1, t0) ) || ( is_less ( h1, h0) && !is_less ( t0, t1) )
75
+ } ;
76
+ if check_existing_run {
77
+ let ( run_len, was_reversed) = find_existing_run ( v, is_less) ;
67
78
68
- // SAFETY: find_existing_run promises to return a valid run_len.
69
- unsafe { intrinsics:: assume ( run_len <= len) } ;
79
+ // SAFETY: find_existing_run promises to return a valid run_len.
80
+ unsafe { intrinsics:: assume ( run_len <= len) } ;
70
81
71
- if run_len == len {
72
- if was_reversed {
73
- v. reverse ( ) ;
74
- }
82
+ if run_len == len {
83
+ if was_reversed {
84
+ v. reverse ( ) ;
85
+ }
75
86
76
- // It would be possible to a do in-place merging here for a long existing streak. But that
77
- // makes the implementation a lot bigger, users can use `slice::sort` for that use-case.
78
- return ;
87
+ // It would be possible to a do in-place merging here for a long existing streak. But that
88
+ // makes the implementation a lot bigger, users can use `slice::sort` for that use-case.
89
+ return ;
90
+ }
79
91
}
80
92
81
93
// Limit the number of imbalanced partitions to `2 * floor(log2(len))`.
0 commit comments