I wanted to compare radix_sort to quick_sort for values limited to 0..127 so I implemented this :
void bin_radix_sort(int *a, const size_t size, int digits) {
assert(digits % 2 == 0);
int *b = malloc(size * sizeof(int));
for (int exp = 0; exp < digits; exp++) {
// Count elements
size_t count[2] = {0};
for (size_t i = 0; i < size; i++)
count[(a[i] >> exp) & 1]++;
// Cumulative sum
count[1] += count[0];
// Build output array
for (int i = size - 1; i >= 0; i--)
b[--count[(a[i] >> exp) & 1]] = a[i];
int *p = a; a = b; b = p;
};
free(b);
}
I was able to compare it to qsort
with :
struct timespec start;
void tic() {
timespec_get(&start, TIME_UTC);
}
double toc() {
struct timespec stop;
timespec_get(&stop, TIME_UTC);
return stop.tv_sec - start.tv_sec + (
stop.tv_nsec - start.tv_nsec
) * 1e-9;
}
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
int main(void) {
const size_t n = 1024 * 1024 * 50;
printf("Init memory (%ld MB)...\n", n / 1024 / 1024 * sizeof(int));
int *data = calloc(n, sizeof(int));
printf("Sorting n = %ld data elements...\n", n);
size_t O;
tic();
O = n * log(n);
qsort(data, n, sizeof(data[0]), cmpfunc);
printf("%ld %lf s\n", O, toc());
int d = 6;
tic();
O = d * (n + 2);
bin_radix_sort(data, n, d);
printf("%ld %lf s\n", O, toc());
}
This gives me this output:
$ gcc -Os bench.c -lm
$ ./a.out
Init memory (200 MB)...
Sorting n = 52428800 data elements...
931920169 1.600909 s
314572812 0.963436 s
I guess my code needs code-review since I was expecting to be six times better than quick sort.
int *data = calloc(n, sizeof(int));
. I'd expect some random filller fordata[]
. Was it the intention to compare perforce with the special case of all zero value? \$\endgroup\$