C Fundamentals
Algorithms · data structures · cryptography · systems — pure C11, zero deps
Loading...
Searching...
No Matches
benchmark.c
Go to the documentation of this file.
1/**
2 * @file benchmark.c
3 * @brief Empirical comparison of all five sort algorithms.
4 *
5 * For each of {100, 1000, 10000} random integers, run each sort against
6 * the same input and report wall-clock time in milliseconds. Output is
7 * a Markdown table so it can be pasted straight into READMEs.
8 */
9
10#include "sorts.h"
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <time.h>
15
16typedef void (*sort_fn)(int *, size_t);
17
18typedef struct {
19 const char *name;
22
23static const sort_entry_t SORTS[] = {
24 {"Selection", selection_sort_ints},
25 {"Bubble", bubble_sort_ints},
26 {"Insertion", insertion_sort_ints},
27 {"Quicksort", quicksort_ints},
28 {"Merge", merge_sort_ints},
29};
30static const size_t N_SORTS = sizeof(SORTS) / sizeof(SORTS[0]);
31
32static const size_t SIZES[] = {100, 1000, 10000};
33static const size_t N_SIZES = sizeof(SIZES) / sizeof(SIZES[0]);
34
35/** Fills `out` with `n` deterministically-shuffled integers in [0, n). */
36static void fill_random(int *out, size_t n, unsigned seed) {
37 srand(seed);
38 for (size_t i = 0; i < n; i++) out[i] = (int)(rand() % (int)n);
39}
40
41static double time_sort_ms(sort_fn fn, int *arr, size_t n) {
42 struct timespec t0, t1;
43 clock_gettime(CLOCK_MONOTONIC, &t0);
44 fn(arr, n);
45 clock_gettime(CLOCK_MONOTONIC, &t1);
46 return (t1.tv_sec - t0.tv_sec) * 1000.0
47 + (t1.tv_nsec - t0.tv_nsec) / 1e6;
48}
49
50int main(void) {
51 printf("# Sort benchmarks (random integers)\n\n");
52 printf("| Algorithm ");
53 for (size_t s = 0; s < N_SIZES; s++) printf("| n=%-6zu ", SIZES[s]);
54 printf("|\n|------------");
55 for (size_t s = 0; s < N_SIZES; s++) printf("|---------");
56 printf("|\n");
57
58 /* Allocate the largest buffer once. */
59 size_t max_n = SIZES[N_SIZES - 1];
60 int *original = malloc(max_n * sizeof(int));
61 int *working = malloc(max_n * sizeof(int));
62 if (!original || !working) {
63 fprintf(stderr, "out of memory\n");
64 free(original); free(working);
65 return EXIT_FAILURE;
66 }
67
68 for (size_t i = 0; i < N_SORTS; i++) {
69 printf("| %-10s ", SORTS[i].name);
70 for (size_t s = 0; s < N_SIZES; s++) {
71 size_t n = SIZES[s];
72 fill_random(original, n, 42 /* deterministic */);
73 memcpy(working, original, n * sizeof(int));
74 double ms = time_sort_ms(SORTS[i].fn, working, n);
75 printf("| %7.2fms ", ms);
76 }
77 printf("|\n");
78 }
79
80 free(original);
81 free(working);
82 return EXIT_SUCCESS;
83}
void(* sort_fn)(int *, size_t)
Definition benchmark.c:16
static double time_sort_ms(sort_fn fn, int *arr, size_t n)
Definition benchmark.c:41
static void fill_random(int *out, size_t n, unsigned seed)
Definition benchmark.c:36
int main(void)
Definition benchmark.c:50
static const sort_entry_t SORTS[]
Definition benchmark.c:23
static const size_t SIZES[]
Definition benchmark.c:32
static const size_t N_SIZES
Definition benchmark.c:33
static const size_t N_SORTS
Definition benchmark.c:30
void bubble_sort_ints(int *arr, size_t n)
Definition bubble_sort.c:30
void insertion_sort_ints(int *arr, size_t n)
void merge_sort_ints(int *arr, size_t n)
Definition merge_sort.c:66
void quicksort_ints(int *arr, size_t n)
Definition quicksort.c:76
void selection_sort_ints(int *arr, size_t n)
Unified header for all sorting algorithms.
Definition benchmark.c:18
sort_fn fn
Definition benchmark.c:20
const char * name
Definition benchmark.c:19