int main(void) { int i; plan_tests(2); { double init[16] = { 29, 16, 25, 14, 21, 12, 17, 10, 13, 8, 9, 6, 5, 4, 1, 2 }, expect[16], actual[16]; dumpd(init, "unsorted"); double t0 = tick(); for (i = 0; i < LOOPS; ++i) { memcpy(expect, init, sizeof(init)); qsort(expect, 16, sizeof(double), (cmpfn_t)cmpd); } double t1 = tick(); dumpd(expect, "sorted"); double t2 = tick(); for (i = 0; i < LOOPS; ++i) { memcpy(actual, init, sizeof(init)); insort(actual); } double t3 = tick(); for (i = 0; i < LOOPS; ++i) { memcpy(actual, init, sizeof(init)); ssesort16d(actual); } int j, rank[16]; double work[16]; double t4 = tick(); for (i = 0; i < LOOPS; ++i) { memcpy(work, init, sizeof(init)); sserank16d(work, rank); for (j = 0; j < 16; ++j) actual[j] = init[rank[j]]; } double t5 = tick(); if (!ok(!memcmp(actual, expect, sizeof(actual)), "sserank output is sorted")) dumpd(actual, "actual"); if (!ok(!memcmp(actual, work, sizeof(actual)), "ssesort output is sorted")) dumpd(actual, "actual"); fprintf(stderr, "x %d: qsort: %.4f insertion: %.4f ssesort: %.4f sserank: %.4f\n", LOOPS, t1 - t0, t3 - t2, t4 - t3, t5 - t4); } return exit_status(); }
void sserank16d(double keys[16], int rank[16]) { int i, dist[16] = {}; uint8_t lsb[16]; for (i = 0; i < 16; ++i) dist[LSB(keys[i]) & 15]++; for (i = 0; i < 15; ++i) dist[i + 1] += dist[i]; for (i = 0; i < 16; ++i) { lsb[i] = LSB(keys[i]); LSB(keys[i]) = (lsb[i] & ~15) | dist[lsb[i] & 15]++; } ssesort16d(keys); // Populate rank and restore low byte of each key: for (i = 0; i < 16; ++i) LSB(keys[i]) = lsb[rank[i] = LSB(keys[i]) & 15]; }