add netbsd nl(1)
[rofl0r-hardcore-utils.git] / benchmark.c
blobb7d87c22bf26df7b54bd0432d4a280361484868d
1 #define _POSIX_C_SOURCE 200809L
2 #include <time.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <signal.h>
6 #include <sys/wait.h>
7 #include <assert.h>
8 #include <ctype.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdio.h>
13 static int run(char** argv) {
14 pid_t child, ret;
15 int stat_loc;
16 if((child = fork()) == 0) {
17 execvp(argv[0], argv);
18 perror("execvp");
19 _exit(1);
20 } else {
21 ret = waitpid(child, &stat_loc, 0);
22 assert(ret == child);
23 return WIFEXITED(stat_loc) ? 0 : WTERMSIG(stat_loc);
25 return 0;
28 static void usage() {
29 printf(
30 "benchmark N COMMAND [ARGS...]\n"
31 "runs COMMAND (with ARGS) N times and prints timings.\n"
33 exit(1);
36 #define NANOSECS 1000000000LL
38 long long timespectoll(struct timespec *ts) {
39 return ts->tv_sec*NANOSECS + ts->tv_nsec;
42 char *fmt(long long n) {
43 char buf[256];
44 sprintf(buf, "%lld.%04lld", n/NANOSECS, (n%NANOSECS)/(NANOSECS/1000));
45 return strdup(buf);
48 int main(int argc, char** argv) {
49 if(argc < 3 || !isdigit(argv[1][0])) usage();
50 int i, n = atoi(argv[1]);
51 argv++;
52 argv++;
53 long long *results = calloc(n, sizeof *results);
54 for (i=0; i<n; ++i) {
55 struct timespec b_start, b_end;
56 assert(0 == clock_gettime(CLOCK_MONOTONIC, &b_start));
57 run(argv);
58 assert(0 == clock_gettime(CLOCK_MONOTONIC, &b_end));
59 results[i] = timespectoll(&b_end) - timespectoll(&b_start);
61 long long best = 0x7fffffffffffffffLL, sum = 0;
62 for (i=0; i<n; ++i) {
63 if(results[i] < best) best = results[i];
64 sum += results[i] ;
66 printf("called %d times, best result: %ss, avg: %ss, total: %ss\n",
67 n, fmt(best), fmt(sum/(long long)n), fmt(sum));
68 return 0;