Last active
February 22, 2022 22:14
-
-
Save flavorjones/e68bf8663edf2a8147b5380db71a9920 to your computer and use it in GitHub Desktop.
benchmark libxml2 strlen - https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/147
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
#include <stdlib.h> | |
#include <stdio.h> | |
#include <sys/time.h> | |
#include <string.h> | |
#include <limits.h> | |
long time_in_ms() | |
{ | |
struct timeval tv; | |
gettimeofday(&tv, NULL); | |
return (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000.0 ; | |
} | |
long elapsed_ms_since(long start) | |
{ | |
return time_in_ms() - start ; | |
} | |
#define N_ITERATIONS 10000000 | |
int xmlStrlen(const char *str); | |
int xmlStrlenFast(const char* str); | |
static int xmlStrlenStatic(const char* str) { | |
size_t len = str ? strlen((const char *)str) : 0; | |
return(len > INT_MAX ? 0 : len); | |
} | |
int main(int argc, char **argv) | |
{ | |
int sizes[] = { 1, 2, 3, 4, 8, 16, 32, 64, 128, 256, 512 }; | |
int sizes_len = sizeof(sizes) / sizeof(int); | |
long start_time, elapsed_ms; | |
int j, jsize; | |
printf("iterating %d times ...\n\n", N_ITERATIONS); | |
printf("%10s %12s %12s %12s %12s\n", "", "v2.9.13", "baseline", "#147", "#115"); | |
printf("%10s %12s %12s %12s %12s\n", "length", "xmlStrlen()", "strlen()", "xmlFast()", "xmlStatic()"); | |
for (jsize = 0 ; jsize < sizes_len ; ++jsize) { | |
char *subject = malloc(sizes[jsize]+1); | |
for (j = 0 ; j < sizes[jsize] ; ++j) { | |
subject[j] = 'x'; | |
} | |
subject[sizes[jsize]] = 0; | |
printf("%10d", sizes[jsize]); | |
start_time = time_in_ms(); | |
for (j = 0 ; j < N_ITERATIONS ; ++j) { | |
if (xmlStrlen(subject) != sizes[jsize]) { abort(); } | |
subject[0] = 'x'; | |
} | |
printf(" %9ld ms", elapsed_ms_since(start_time)); | |
start_time = time_in_ms(); | |
for (j = 0 ; j < N_ITERATIONS ; ++j) { | |
if (strlen(subject) != sizes[jsize]) { abort(); } | |
subject[0] = 'x'; | |
} | |
printf(" %9ld ms", elapsed_ms_since(start_time)); | |
start_time = time_in_ms(); | |
for (j = 0 ; j < N_ITERATIONS ; ++j) { | |
if (xmlStrlenFast(subject) != sizes[jsize]) { abort(); } | |
subject[0] = 'x'; | |
} | |
printf(" %9ld ms", elapsed_ms_since(start_time)); | |
start_time = time_in_ms(); | |
for (j = 0 ; j < N_ITERATIONS ; ++j) { | |
if (xmlStrlenStatic(subject) != sizes[jsize]) { abort(); } | |
subject[0] = 'x'; | |
} | |
printf(" %9ld ms", elapsed_ms_since(start_time)); | |
printf("\n"); | |
free(subject); | |
} | |
printf("\n"); | |
exit(0); | |
} |
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
#include <string.h> | |
#include <limits.h> | |
int xmlStrlen(const char *str) { | |
size_t len = 0; | |
if (str == NULL) return(0); | |
while (*str != 0) { /* non input consuming */ | |
str++; | |
len++; | |
} | |
return(len > INT_MAX ? 0 : len); | |
} | |
int xmlStrlenFast(const char* str) { | |
size_t len = str ? strlen((const char *)str) : 0; | |
return(len > INT_MAX ? 0 : len); | |
} |
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
CFLAGS = -std=c89 | |
default: run | |
benchmark-O0.o: benchmark.c | |
$(CC) -O0 $(CFLAGS) -c -o benchmark-O0.o benchmark.c | |
lib-O0.o: lib.c | |
$(CC) -O0 $(CFLAGS) -c -o lib-O0.o lib.c | |
benchmark-O0: benchmark-O0.o lib-O0.o | |
$(CC) -O0 $(CFLAGS) -o benchmark-O0 benchmark-O0.o lib-O0.o | |
benchmark-O1.o: benchmark.c | |
$(CC) -O1 $(CFLAGS) -c -o benchmark-O1.o benchmark.c | |
lib-O1.o: lib.c | |
$(CC) -O1 $(CFLAGS) -c -o lib-O1.o lib.c | |
benchmark-O1: benchmark-O1.o lib-O1.o | |
$(CC) -O1 $(CFLAGS) -o benchmark-O1 benchmark-O1.o lib-O1.o | |
benchmark-O2.o: benchmark.c | |
$(CC) -O2 $(CFLAGS) -c -o benchmark-O2.o benchmark.c | |
lib-O2.o: lib.c | |
$(CC) -O2 $(CFLAGS) -c -o lib-O2.o lib.c | |
benchmark-O2: benchmark-O2.o lib-O2.o | |
$(CC) -O2 $(CFLAGS) -o benchmark-O2 benchmark-O2.o lib-O2.o | |
benchmark-O3.o: benchmark.c | |
$(CC) -O3 $(CFLAGS) -c -o benchmark-O3.o benchmark.c | |
lib-O3.o: lib.c | |
$(CC) -O3 $(CFLAGS) -c -o lib-O3.o lib.c | |
benchmark-O3: benchmark-O3.o lib-O3.o | |
$(CC) -O3 $(CFLAGS) -o benchmark-O3 benchmark-O3.o lib-O3.o | |
all: benchmark-O0 benchmark-O1 benchmark-O2 benchmark-O3 | |
run: all | |
./benchmark-O0 | |
./benchmark-O1 | |
./benchmark-O2 | |
./benchmark-O3 | |
clean: | |
rm -f benchmark-O* *.o |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment