in-place algorithm and fix of perf bug where we not early exited in spsort after insertion sorting small buckets so they were sorted again by us too :-)
This commit is contained in:
parent
b1ab4f2f87
commit
36ea38940b
@ -134,55 +134,39 @@ inline void spsort(uint32_t *t, int n, int m = 32);
|
|||||||
|
|
||||||
/** Helper function that puts elements higher then mid to the top of the array and lower to the bottom. Returns number of bottoms */
|
/** Helper function that puts elements higher then mid to the top of the array and lower to the bottom. Returns number of bottoms */
|
||||||
inline int internal_array_separate(uint32_t *t, int n, uint32_t mid) {
|
inline int internal_array_separate(uint32_t *t, int n, uint32_t mid) {
|
||||||
/*
|
if(n > 0) {
|
||||||
// Init left-right "write head" indices
|
// Two heads that also read & write (both)
|
||||||
int left = 0;
|
int left = 0;
|
||||||
int right = n - 1;
|
int right = n - 1;
|
||||||
uint32_t current = t[left];
|
while(left < right) {
|
||||||
bool current_is_left = true;
|
bool lok = (t[left] < mid);
|
||||||
|
bool rok = (t[right] >= mid);
|
||||||
// Separate to the ends of the array (in-place)
|
if(lok || rok) {
|
||||||
for(int i = 0; i < n; ++i) {
|
// HOT PATH
|
||||||
if(current < mid) {
|
// Move heads until both in wrong location
|
||||||
const auto tmp = t[left];
|
left += lok;
|
||||||
t[left++] = current;
|
right -= rok;
|
||||||
current = current_is_left ? t[left] : tmp;
|
} else {
|
||||||
current_is_left = true;
|
// REGULAR PATH
|
||||||
|
// Both in wrong location - xchg them!
|
||||||
} else {
|
auto tmp = t[right];
|
||||||
const auto tmp = t[right];
|
t[right] = t[left];
|
||||||
t[right--] = current;
|
t[left] = tmp;
|
||||||
current = tmp;
|
++left;
|
||||||
current = !current_is_left ? t[right] : tmp;
|
--right;
|
||||||
current_is_left = false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Edge-case increment if single elem happens in middle in the end
|
||||||
|
left += ((left == right) && (t[left] < mid));
|
||||||
|
|
||||||
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
return left;
|
return 0;
|
||||||
*/
|
|
||||||
|
|
||||||
// FIXME: bad quality debug code to remove
|
|
||||||
std::vector<uint32_t> v(n);
|
|
||||||
int left = 0;
|
|
||||||
int right = n - 1;
|
|
||||||
auto current = t[0];
|
|
||||||
for(int i = 0; i < n; ++i) {
|
|
||||||
if(current < mid) {
|
|
||||||
v[left++] = current;
|
|
||||||
current = t[i + 1];
|
|
||||||
} else {
|
|
||||||
v[right--] = current;
|
|
||||||
current = t[i + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(int i = 0; i < n; ++i) {
|
|
||||||
t[i] = v[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: [spsort] In-place variant that looks like a quicksort-kind-of-thing:
|
// ALGO: [spsort] In-place variant that looks like a quicksort-kind-of-thing:
|
||||||
// - I realized that in-placing make this similar to quicksort actually
|
// - I realized that in-placing make this similar to quicksort actually
|
||||||
// - We check if the thing is small enough for insertion sorting in-place
|
// - We check if the thing is small enough for insertion sorting in-place
|
||||||
// - If not, we calculate low-mid-high
|
// - If not, we calculate low-mid-high
|
||||||
@ -205,6 +189,7 @@ inline void internal_spsort(uint32_t *t, int n, int m, uint32_t low, uint32_t mi
|
|||||||
// Makes small arrays sort fast otherwise we need to go down m == 2 or such!
|
// Makes small arrays sort fast otherwise we need to go down m == 2 or such!
|
||||||
if(n < m) {
|
if(n < m) {
|
||||||
binsertion_sort(t, n);
|
binsertion_sort(t, n);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto left = internal_array_separate(t, n, mid);
|
auto left = internal_array_separate(t, n, mid);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user