threeway further optimizations

This commit is contained in:
Richard Thier 2025-04-08 01:18:40 +02:00
parent a465110170
commit bc500c84e8
2 changed files with 41 additions and 3 deletions

16
qsort.h
View File

@ -102,12 +102,16 @@ static inline pret3 partition3(uint32_t array[], int low, int high, uint32_t piv
/* index until smaller or eq elements lay */ /* index until smaller or eq elements lay */
int i = (low - 1); int i = (low - 1);
uint32_t pc = 0;
/* traverse each element of the array */ /* traverse each element of the array */
/* compare them with the pivot */ /* compare them with the pivot */
#pragma GCC unroll 4 #pragma GCC unroll 4
for (int j = low; j < high; ++j) { for (int j = low; j <= high; ++j) {
if (array[j] < pivot) { /* Branchless pivot-count */
pc += (array[j] == pivot);
if(array[j] < pivot) {
/* if element smaller than pivot is found */ /* if element smaller than pivot is found */
/* swap it with the greater element pointed by i */ /* swap it with the greater element pointed by i */
++i; ++i;
@ -117,6 +121,14 @@ static inline pret3 partition3(uint32_t array[], int low, int high, uint32_t piv
} }
} }
/* Can spare out the second loop in these cases */
if(pc < 2) {
pret3 ret;
ret.leftend = i;
ret.rightend = i + 1;
return ret;
}
/* index until smaller or eq elements lay */ /* index until smaller or eq elements lay */
int i2 = (high + 1); int i2 = (high + 1);

View File

@ -37,7 +37,7 @@ static inline void zssort(uint32_t array[], int low, int high) {
} }
} }
/* ZSSORT */ /* ZSSORTR */
/** Always at most log(n) space needing randomized quicksort variant */ /** Always at most log(n) space needing randomized quicksort variant */
static inline void zssort_rand(uint32_t array[], int low, int high, rpivotstate *state) { static inline void zssort_rand(uint32_t array[], int low, int high, rpivotstate *state) {
@ -63,6 +63,32 @@ static inline void zssort_rand(uint32_t array[], int low, int high, rpivotstate
} }
} }
/* THREEWAY_ZS */
/** Always at most log(n) space needing randomized quicksort variant */
static inline void zssort_rand3(uint32_t array[], int low, int high, rpivotstate *state) {
while (low < high) {
int pi = pick_pivot(state, (high + 1) - low) + low;
pret3 res = partition3(array, low, high, array[pi]);
/* If we recurse only the smaller part */
/* That ensures at most n/2 elements can */
/* be on any given level of the recursion */
/* tree: that is we ensure log2(N) memuse! */
if((res.leftend - low) < (high - res.rightend)) {
// Left smaller: recurse left of pivot
zssort_rand3(array, low, res.leftend, state);
// (*) Update partitioning loop for remaining part
low = res.rightend;
} else {
// Right smaller: recurse right of pivot
zssort_rand3(array, res.rightend, high, state);
// (*) Update partitioning loop for remaining part
high = res.leftend; /* high inclusive! */
}
}
}
/* ZSSORTC */ /* ZSSORTC */
/** Always at most log(n) space needing randomized quicksort variant - with checking for sameconst-arrays */ /** Always at most log(n) space needing randomized quicksort variant - with checking for sameconst-arrays */