Last active
February 20, 2024 19:23
-
-
Save aryelgois/a6b19e1416061b18e520683dc5755d73 to your computer and use it in GitHub Desktop.
Benchmark strlen vs check \0 vs snprintf
This file contains hidden or 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
#include <stdio.h> | |
#include <string.h> | |
#include <time.h> | |
// header ---------------------------------------------------------------- {{{1 | |
typedef struct { | |
clock_t start; | |
clock_t end; | |
} Elapsed; | |
static inline void elapsed_start(Elapsed *e); | |
static inline void elapsed_end(Elapsed *e); | |
double elapsed_result(Elapsed e); | |
void print_elapsed(Elapsed e); | |
static inline int size_array1(char *data); | |
static inline int size_array2(char *data); | |
static inline int loop_array1(char *data); | |
static inline int loop_array2(char *data); | |
static inline int loop_array3(char *data); | |
// main() ---------------------------------------------------------------- {{{1 | |
int main(void) | |
{ | |
int res; | |
Elapsed lap = {0}; | |
char data[4096]; | |
memset(data, 'X', sizeof data); | |
data[sizeof data - 1] = '\0'; | |
elapsed_start(&lap); | |
res = size_array1(data); | |
elapsed_end(&lap); | |
printf("size(1): %d ", res); | |
print_elapsed(lap); | |
elapsed_start(&lap); | |
res = size_array2(data); | |
elapsed_end(&lap); | |
printf("size(2): %d ", res); | |
print_elapsed(lap); | |
puts(""); | |
elapsed_start(&lap); | |
res = loop_array1(data); | |
elapsed_end(&lap); | |
printf("loop(1): %d ", res); | |
print_elapsed(lap); | |
elapsed_start(&lap); | |
res = loop_array2(data); | |
elapsed_end(&lap); | |
printf("loop(2): %d ", res); | |
print_elapsed(lap); | |
elapsed_start(&lap); | |
res = loop_array3(data); | |
elapsed_end(&lap); | |
printf("loop(3): %d ", res); | |
print_elapsed(lap); | |
return 0; | |
} | |
// Test functions -------------------------------------------------------- {{{1 | |
// O(n) | |
static inline int size_array1(char *data) | |
{ | |
return strlen(data); | |
} | |
// O(1) ??? | |
static inline int size_array2(char *data) | |
{ | |
return snprintf(NULL, 0, "%s", data); | |
} | |
// O(n**2) | |
static inline int loop_array1(char *data) | |
{ | |
int i; | |
for (i = 0; i < strlen(data); i++); | |
return i; | |
} | |
// O(n) | |
static inline int loop_array2(char *data) | |
{ | |
int i; | |
int sz = strlen(data); | |
for (i = 0; i < sz; i++); | |
return i; | |
} | |
// O(n) | |
static inline int loop_array3(char *data) | |
{ | |
int i; | |
for (i = 0; data[i] != '\0'; i++); | |
return i; | |
} | |
// Elapsed --------------------------------------------------------------- {{{1 | |
static inline void elapsed_start(Elapsed *e) | |
{ | |
e->start = clock(); | |
} | |
static inline void elapsed_end(Elapsed *e) | |
{ | |
e->end = clock(); | |
} | |
double elapsed_result(Elapsed e) | |
{ | |
return (double)(e.end - e.start) / CLOCKS_PER_SEC; | |
} | |
void print_elapsed(Elapsed e) | |
{ | |
printf("elapsed: %f\n", elapsed_result(e)); | |
} | |
// }}}1 | |
// vim: fdm=marker |
gcc -O1 -o run benchmark_strlen.c && ./run
ouput:
size(1): 4095 elapsed: 0.000003
size(2): 4095 elapsed: 0.000004
loop(1): 4095 elapsed: 0.000006
loop(2): 4095 elapsed: 0.000004
loop(3): 4095 elapsed: 0.000004
Increasing the size of data
to 1048576 (1024 * 1024):
gcc -o run benchmark_strlen.c && ./run
output:
size(1): 1048575 elapsed: 0.000058
size(2): 1048575 elapsed: 0.000231
loop(1): 1048575 elapsed: 16.185053
loop(2): 1048575 elapsed: 0.001922
loop(3): 1048575 elapsed: 0.002099
With optimization:
gcc -O1 -o run benchmark_strlen.c && ./run
output:
size(1): 1048575 elapsed: 0.000029
size(2): 1048575 elapsed: 0.000093
loop(1): 1048575 elapsed: 0.000408
loop(2): 1048575 elapsed: 0.000377
loop(3): 1048575 elapsed: 0.000357
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
gcc -o run benchmark_strlen.c && ./run
output:
Is
snprintf
really O(1)?Does
strlen
check the buffer size? Is it ok to just check for\0
?