Created
November 2, 2012 13:26
-
-
Save Mons/4001364 to your computer and use it in GitHub Desktop.
Comparison of strlen and for(;;buf++)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Compile me: | |
$ gcc -Wall -o strlen-bench strlen-bench.c -lrt -g -ggdb -O3 | |
*/ | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <sys/time.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#include <time.h> | |
#include <endian.h> | |
const char *x = "HTTP/0.9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | |
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxx" | |
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"; | |
typedef int (*testfunc)( const char *buf ); | |
typedef union { | |
const unsigned char *c; | |
const uint32_t *i; | |
const uint64_t *q; | |
const char *_c1; | |
} uniptr; | |
static int test1(const char *buf) { | |
const char *p = buf; | |
for (;;p++) { | |
if (*p ==0) return p-buf; | |
} | |
return 0; | |
} | |
static int test2(const char *buf) { | |
return strlen(buf); | |
} | |
typedef struct { | |
time_t sec; | |
long int nsec; | |
intmax_t delta; | |
} mytimediff; | |
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; | |
} | |
long double timeit( intmax_t maxtime, testfunc test, const char * data ) { | |
struct timespec t0,t1,t2; | |
mytimediff d; | |
intmax_t i,k, total; | |
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t0); | |
long double ops; | |
for ( i = 1; i < 0xfffffff ; i <<= 1 ) { | |
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t1); | |
for ( k=0; k < i; k++) { | |
test(data); | |
} | |
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t2); | |
total += i; | |
d = timedelta( t1,t2 ); | |
ops = i*1E9/d.delta; | |
d = timedelta( t0,t2 ); | |
if ( d.delta > maxtime ) { | |
printf(" delta = %jd.%09jds (%jd us); (ops = %.0Lf/s)\n", d.sec, d.nsec, d.delta, ops ); | |
return ops; | |
break; | |
} | |
} | |
return -1; | |
} | |
int main(void) { | |
//return; | |
const char *test = x; | |
printf("test1 = %d\n", test1(test)); | |
printf("test2 = %d\n", test2(test)); | |
long double ops1 = timeit( 1E09, test1, test ); | |
long double ops2 = timeit( 1E09, test2, test ); | |
printf("ops1 = %Lf\n", ops1); | |
printf("ops2 = %Lf\n", ops2); | |
printf("ops2/ops1 = ( %+0.2Lf%% = x%0.1Lf )\n", 100.0 * ( ops2 - ops1 ) / ops1, ops2/ops1 ); | |
printf("ops1/ops2 = ( %+0.2Lf%% = x%0.1Lf )\n", 100.0 * ( ops1 - ops2 ) / ops2, ops1/ops2 ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment