Skip to content

Instantly share code, notes, and snippets.

@aryelgois
Last active February 20, 2024 19:23
Show Gist options
  • Save aryelgois/a6b19e1416061b18e520683dc5755d73 to your computer and use it in GitHub Desktop.
Save aryelgois/a6b19e1416061b18e520683dc5755d73 to your computer and use it in GitHub Desktop.
Benchmark strlen vs check \0 vs snprintf
#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
@aryelgois
Copy link
Author

aryelgois commented Feb 20, 2024

gcc -o run benchmark_strlen.c && ./run

output:

size(1): 4095  elapsed: 0.000003
size(2): 4095  elapsed: 0.000004

loop(1): 4095  elapsed: 0.000328
loop(2): 4095  elapsed: 0.000017
loop(3): 4095  elapsed: 0.000018

@aryelgois
Copy link
Author

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

@aryelgois
Copy link
Author

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