diff options
-rw-r--r-- | bench.c | 36 | ||||
-rw-r--r-- | generators.c | 74 | ||||
-rw-r--r-- | generators.h | 8 | ||||
-rw-r--r-- | testcases.c | 94 | ||||
-rw-r--r-- | testcases.h | 17 |
5 files changed, 119 insertions, 110 deletions
@@ -3,33 +3,13 @@ #include <stdlib.h> #include <time.h> -#include "generators.h" +#include "testcases.h" #include "sorters.h" -#define MIN_SIZE 10000 -#define MAX_SIZE 10000000 - -static int buffer[MAX_SIZE]; -static unsigned long comparisons; - -static int compare(const void *a, const void *b) -{ - const int *aa = a; - const int *bb = b; - - comparisons++; - if (*aa < *bb) - return -1; - else if (*aa > *bb) - return 1; - else - return 0; -} - #define CMP_WIDTH 12 #define MS_WIDTH 6 #define SORT_WIDTH 16 -#define GEN_WIDTH (CMP_WIDTH + MS_WIDTH + 1) +#define TEST_WIDTH (CMP_WIDTH + MS_WIDTH + 1) #define SIZE_WIDTH 10 static inline unsigned long timediff_ms(struct timespec *start, struct timespec *stop) @@ -42,22 +22,22 @@ int main() struct timespec start, stop; printf("%-*s ", SORT_WIDTH, ""); - for (const struct generator *g = generators; g->name; g++) - printf("%*s ", GEN_WIDTH, g->name); + for (const struct testcase *t = testcases; t->name; t++) + printf("%*s ", TEST_WIDTH, t->name); printf(" %*s\n%-*s ", SIZE_WIDTH, "elements", SORT_WIDTH, ""); - for (const struct generator *g = generators; g->name; g++) + for (const struct testcase *t = testcases; t->name; t++) printf("%*s %*s ", CMP_WIDTH, "compares", MS_WIDTH, "ms"); puts(""); for (const struct sorter *s = sorters; s->name; s++) { for (size_t size = MIN_SIZE; size <= MAX_SIZE; size *= 10) { printf("%-*s ", SORT_WIDTH, size == MIN_SIZE ? s->name : ""); - for (const struct generator *g = generators; g->name; g++) { + for (const struct testcase *t = testcases; t->name; t++) { comparisons = 0; - g->func(buffer, size); + t->init(buffer, size); if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start)) abort(); - s->func(buffer, size, sizeof(int), compare); + s->func(buffer, size, sizeof(int), t->cmp); if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stop)) abort(); printf("%*lu %*lu ", CMP_WIDTH, comparisons, MS_WIDTH, timediff_ms(&start, &stop)); diff --git a/generators.c b/generators.c deleted file mode 100644 index 4c73454..0000000 --- a/generators.c +++ /dev/null @@ -1,74 +0,0 @@ -#include <limits.h> -#include <stddef.h> -#include <stdlib.h> - -#include "generators.h" - -static void generate_random(int *buffer, size_t size) -{ - srandom(1); - for (size_t i = 0; i < size; i++) buffer[i] = random(); - - /* compress the values to nice small numbers to make debugging nicer */ -#if 0 - int maxcompressed = -1; - for (size_t compressed = 0; compressed < size; compressed++) { - size_t minidx = -1; - for (size_t i = 0; i < size; i++) { - if (maxcompressed < buffer[i] && (minidx >= size || buffer[i] < buffer[minidx])) - minidx = i; - } - buffer[minidx] = ++maxcompressed; - } -#endif -} - -static void generate_sorted(int *buffer, size_t size) -{ - for (size_t i = 0; i < size; i++) buffer[i] = i; -} - -static void generate_reverse(int *buffer, size_t size) -{ - for (size_t i = 0; i < size; i++) buffer[i] = size - i - 1; -} - -static void generate_constant(int *buffer, size_t size) -{ - for (size_t i = 0; i < size; i++) buffer[i] = 42; -} - -static void add_noise(int *buffer, size_t size) -{ - int noisemax = size / 4; - int noiseoff = size / 8; - - srandom(1); - for (size_t i = 0; i < size; i++) { - if (random() < 0.2 * RAND_MAX) { - buffer[i] += random() % noisemax - noiseoff; - } - } -} - -static void generate_sorted_noise(int *buffer, size_t size) -{ - generate_sorted(buffer, size); - add_noise(buffer, size); -} - -static void generate_reverse_noise(int *buffer, size_t size) -{ - generate_reverse(buffer, size); - add_noise(buffer, size); -} - -const struct generator generators[] = { - { .name = "random", .func = generate_random }, - { .name = "sorted", .func = generate_sorted }, - { .name = "reverse", .func = generate_reverse }, - { .name = "constant", .func = generate_constant }, - { .name = "sorted+noise", .func = generate_sorted_noise }, - { .name = "reverse+noise", .func = generate_reverse_noise }, - { 0 } -}; diff --git a/generators.h b/generators.h deleted file mode 100644 index e08a0be..0000000 --- a/generators.h +++ /dev/null @@ -1,8 +0,0 @@ -#include <stddef.h> - -typedef void (*generatorfn)(int *, size_t); - -extern const struct generator { - const char *name; - generatorfn func; -} generators[]; diff --git a/testcases.c b/testcases.c new file mode 100644 index 0000000..612d1c2 --- /dev/null +++ b/testcases.c @@ -0,0 +1,94 @@ +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> + +#include "testcases.h" + +#define MIN_SIZE 10000 +#define MAX_SIZE 10000000 + +int buffer[MAX_SIZE]; +unsigned long comparisons; + +static int compare(const void *a, const void *b) +{ + const int *aa = a; + const int *bb = b; + + comparisons++; + if (*aa < *bb) + return -1; + else if (*aa > *bb) + return 1; + else + return 0; +} + +static void init_random(int *buffer, size_t size) +{ + srandom(1); + for (size_t i = 0; i < size; i++) buffer[i] = random(); + + /* compress the values to nice small numbers to make debugging nicer */ +#if 0 + int maxcompressed = -1; + for (size_t compressed = 0; compressed < size; compressed++) { + size_t minidx = -1; + for (size_t i = 0; i < size; i++) { + if (maxcompressed < buffer[i] && (minidx >= size || buffer[i] < buffer[minidx])) + minidx = i; + } + buffer[minidx] = ++maxcompressed; + } +#endif +} + +static void init_sorted(int *buffer, size_t size) +{ + for (size_t i = 0; i < size; i++) buffer[i] = i; +} + +static void init_reverse(int *buffer, size_t size) +{ + for (size_t i = 0; i < size; i++) buffer[i] = size - i - 1; +} + +static void init_constant(int *buffer, size_t size) +{ + for (size_t i = 0; i < size; i++) buffer[i] = 42; +} + +static void add_noise(int *buffer, size_t size) +{ + int noisemax = size / 4; + int noiseoff = size / 8; + + srandom(1); + for (size_t i = 0; i < size; i++) { + if (random() < 0.2 * RAND_MAX) { + buffer[i] += random() % noisemax - noiseoff; + } + } +} + +static void init_sorted_noise(int *buffer, size_t size) +{ + init_sorted(buffer, size); + add_noise(buffer, size); +} + +static void init_reverse_noise(int *buffer, size_t size) +{ + init_reverse(buffer, size); + add_noise(buffer, size); +} + +const struct testcase testcases[] = { + { .name = "random", .init = init_random, .cmp = compare }, + { .name = "sorted", .init = init_sorted, .cmp = compare }, + { .name = "reverse", .init = init_reverse, .cmp = compare }, + { .name = "constant", .init = init_constant, .cmp = compare }, + { .name = "sorted+noise", .init = init_sorted_noise, .cmp = compare }, + { .name = "reverse+noise", .init = init_reverse_noise, .cmp = compare }, + { 0 } +}; diff --git a/testcases.h b/testcases.h new file mode 100644 index 0000000..036fe5d --- /dev/null +++ b/testcases.h @@ -0,0 +1,17 @@ +#include <stddef.h> + +#include "sorters.h" + +#define MIN_SIZE 10000 +#define MAX_SIZE 10000000 + +extern int buffer[MAX_SIZE]; +extern unsigned long comparisons; + +typedef void (*testinit)(int *, size_t); + +extern const struct testcase { + const char *name; + testinit init; + cmpfun cmp; +} testcases[]; |