Skip to content

Instantly share code, notes, and snippets.

@Mons
Created November 21, 2012 11:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mons/4124526 to your computer and use it in GitHub Desktop.
Save Mons/4124526 to your computer and use it in GitHub Desktop.
Small benchmark utility
/*
Usage:
#include "benchmark.h"
int test1 (va_list ap) {
char *str1 = va_arg( ap, char * );
char *str2 = va_arg( ap, char * );
...
return ...;
}
int test2 (va_list ap) {
char *str1 = va_arg( ap, char * );
char *str2 = va_arg( ap, char * );
...
return ...;
}
int main () {
bench_item tests[2] = {
{ "test1", test1, 0},
{ "test2", test2, 0}
// ^ name of test
// ^ function
// ^ here will be stored result (double)
};
benchmark(1E8, 2, tests, arg1, arg2);
// ^ time to run at least, microseconds (1s = 1E9 us)
// ^ number of items in tests
// ^ arguments to test function
}
//compile with: -lrt
*/
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
typedef int (*testfunc)( va_list ap );
typedef struct {
time_t sec;
long int nsec;
intmax_t delta;
} mytimediff;
typedef struct {
char *name;
testfunc func;
long double ops;
} bench_item;
static inline mytimediff timedelta( struct timespec t1, struct timespec t2 ) {
mytimediff d;
intmax_t delta_nsec = ( (intmax_t)t2.tv_nsec - (intmax_t)t1.tv_nsec );
intmax_t delta_sec = (intmax_t)t2.tv_sec - (intmax_t)t1.tv_sec;
if (delta_nsec < 0) { delta_nsec += 1E9; delta_sec -=1; }
if (delta_sec < 0) { delta_nsec = 1E9 - delta_nsec; }
intmax_t delta = delta_sec*1E9 + delta_nsec;
d.sec = delta_sec;
d.nsec = delta_nsec;
d.delta = delta;
return d;
}
static long double vtimeit( intmax_t maxtime, char *name, testfunc test, va_list ap ) {
struct timeval tv;
struct timespec t0,t1,t2;
mytimediff d;
intmax_t i,k, total;
uint64_t time1, time2;
uint64_t tx1, tx2;
va_list an;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t0);
long double ops;
for ( i = 1; i < 0xfffffff ; i <<= 1 ) {
gettimeofday(&tv, NULL); time1 = tv.tv_sec * 1000000 + tv.tv_usec;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t1);
for ( k=0; k < i; k++) {
va_copy(an,ap);
test(an);
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t2);
gettimeofday(&tv, NULL); time2 = tv.tv_sec * 1000000 + tv.tv_usec;
total += i;
d = timedelta( t1,t2 );
ops = i*1E9/d.delta;
d = timedelta( t0,t2 );
if ( d.delta > maxtime ) {
printf("%-20s: delta = %jd.%09jds (%jd us); (ops = %.0Lf/s)\n", name, d.sec, d.nsec, d.delta, ops );
return ops;
break;
}
}
return -1;
}
static long double timeit( intmax_t maxtime, char * name, testfunc test, ... ) {
va_list ap;
va_start(ap, test);
vtimeit(maxtime, name, test, ap);
}
static int compare_bench_items(const void *a, const void *b) {
long double ad = ((bench_item *)a)->ops;
long double bd = ((bench_item *)b)->ops;
return ad == bd ? 0 : ad > bd ? 1 : -1;
}
static void benchmark( intmax_t maxtime, int count, bench_item items[], ... ) {
int i,k;
va_list ap;
va_list an;
va_start(ap, items);
char tmp[256];
va_copy(an,ap);
int rv = items[0].func( an );
printf("RV = %d\n",rv);
for (i=1; i< count; i++) {
va_copy(an,ap);
int cv = items[i].func( an );
if ( cv != rv ) {
fprintf(stderr, "%s return value (%d) differs from %s (%d)\n", items[i].name, cv, items[0].name, rv);
}
}
for (i=0; i< count; i++) {
items[i].ops = vtimeit( maxtime, items[i].name, items[i].func, ap );
}
qsort( items, count, sizeof( bench_item ), compare_bench_items );
for (k=-2; k < count; k++) {
if (k == -2) {
printf("%21s|","");
for (i=0; i< count; i++) {
int lp = (20 - strlen(items[i].name) )/2+1;
int rp = 20 - strlen(items[i].name) - lp;
printf("%*s%s%*s |", lp, "",items[i].name, rp,"");
//printf("| %-20.20s", items[i].name);
}
printf("\n");
}
else if (k == -1) {
printf("---------------------|");
for (i=0; i< count; i++) {
printf("---------------------|");
}
printf("\n");
}
else {
printf("%-20.20s |", items[k].name);
for (i=0; i< count; i++) {
if (i == k) {
printf("%10s%s%10s|", "","-","");
} else {
snprintf(tmp, 255, "%+0.2Lf%% (x%0.1Lf)", 100.0 * (items[k].ops - items[i].ops) / items[i].ops, (double)items[k].ops/items[i].ops);
int lp = (20 - strlen(tmp) )/2+1;
int rp = 20 - strlen(tmp) - lp;
printf("%*s%s%*s |", lp, "",tmp, rp,"");
//printf(" %-20.20s|", tmp);
}
}
printf("\n");
}
}
printf("\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment