[libc-commits] [libc] [libc][stdlib] Optimize number of comparisons in heap_sort (PR #232602)
Kuan-Wei Chiu via libc-commits
libc-commits at lists.llvm.org
Thu Oct 15 23:04:38 PDT 2026
visitorckw wrote:
I verified that all sorting related unit tests pass (libc.test.src.stdlib.heap_sort_test, libc.test.src.stdlib.quick_sort_test, and libc.test.src.stdlib.qsort_r_test).
I also wrote a small test program building with -DLIBC_QSORT_IMPL=LIBC_QSORT_HEAP_SORT to measure both the number of comparisons and execution time when sorting 100000 random strings over 50 iterations:
```
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 100000
#define ITERS 50
static uint64_t cmp_cnt;
static int cmp_str(const void *a, const void *b) {
cmp_cnt++;
return strcmp(*(const char *const *)a, *(const char *const *)b);
}
int main(void) {
char **orig = malloc(N * sizeof(char *));
char **arr = malloc(N * sizeof(char *));
struct timespec t0, t1;
double total_sec = 0.0;
srand(42);
for (size_t i = 0; i < N; i++) {
orig[i] = malloc(32);
snprintf(orig[i], 32, "prefix_string_%010d", rand());
}
cmp_cnt = 0;
for (int it = 0; it < ITERS; it++) {
memcpy(arr, orig, N * sizeof(char *));
clock_gettime(CLOCK_MONOTONIC, &t0);
qsort(arr, N, sizeof(char *), cmp_str);
clock_gettime(CLOCK_MONOTONIC, &t1);
total_sec += (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) * 1e-9;
}
printf("comparisons per run: %lu, avg time: %.3f ms\n",
cmp_cnt / ITERS, (total_sec * 1e3) / ITERS);
for (size_t i = 0; i < N; i++)
free(orig[i]);
free(orig);
free(arr);
return 0;
}
```
Results on x86-64:
- Before: comparisons per run: 3019211, avg time: 50.570 ms
- After: comparisons per run: 1699624, avg time: 35.989 ms (~43.7% fewer comparisons, ~28.8% faster)
https://github.com/llvm/llvm-project/pull/232602
More information about the libc-commits
mailing list