From ba3ee2cd1682576729b7c0fe77bf8b2b04cb813a Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 6 Aug 2008 15:54:56 +0000 Subject: [PATCH] Add benchmark support. SVN revision: 35355 --- legacy/eina/.cvsignore | 1 + legacy/eina/configure.in | 18 +++ legacy/eina/src/Makefile.am | 12 ++ legacy/eina/src/tests/.cvsignore | 1 + legacy/eina/src/tests/Makefile.am | 21 ++- legacy/eina/src/tests/eina_bench.c | 185 +++++++++++++++++++++++ legacy/eina/src/tests/eina_bench.h | 13 ++ legacy/eina/src/tests/eina_bench_hash.c | 188 ++++++++++++++++++++++++ 8 files changed, 436 insertions(+), 3 deletions(-) create mode 100644 legacy/eina/src/tests/eina_bench.c create mode 100644 legacy/eina/src/tests/eina_bench.h create mode 100644 legacy/eina/src/tests/eina_bench_hash.c diff --git a/legacy/eina/.cvsignore b/legacy/eina/.cvsignore index bef6e979b0..dfcc543190 100644 --- a/legacy/eina/.cvsignore +++ b/legacy/eina/.cvsignore @@ -26,3 +26,4 @@ doc README mkinstalldirs coverage +result diff --git a/legacy/eina/configure.in b/legacy/eina/configure.in index f40ba68646..f9870ae29d 100644 --- a/legacy/eina/configure.in +++ b/legacy/eina/configure.in @@ -58,6 +58,23 @@ AC_ARG_ENABLE([coverage], AC_MSG_CHECKING([whether to use profiling instrumentation]) AC_MSG_RESULT([$enable_coverage]) +# Benchmarking tests + +AC_ARG_ENABLE([tests], + [AC_HELP_STRING([--enable-tests], [enable tests @<:@default=no@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + enable_bench="yes" + else + enable_bench="no" + fi + ], + [enable_bench="no"] +) +AC_MSG_CHECKING([whether tests are built]) +AC_MSG_RESULT([${enable_bench}]) +AM_CONDITIONAL(EINA_ENABLE_BENCH, test "x${enable_bench}" = "xyes") + # Ememoa memory pool AC_ARG_ENABLE([ememoa], @@ -197,6 +214,7 @@ echo "Configuration Options Summary:" echo echo " Tests................: ${enable_tests}" echo " Coverage.............: ${enable_coverage}" +echo " Bench................: ${enable_bench}" echo echo " Memory pool:" echo " Ememoa.............: ${enable_ememoa}" diff --git a/legacy/eina/src/Makefile.am b/legacy/eina/src/Makefile.am index 207ac0d5ce..d7ebc222f8 100644 --- a/legacy/eina/src/Makefile.am +++ b/legacy/eina/src/Makefile.am @@ -1,3 +1,15 @@ SUBDIRS = lib include modules tests MAINTAINERCLEANFILES = Makefile.in + +if EINA_ENABLE_BENCH + +bench: all + make -C tests eina_bench + +else + +bench: + @echo "reconfigure with --enable-bench" + +endif diff --git a/legacy/eina/src/tests/.cvsignore b/legacy/eina/src/tests/.cvsignore index 1d719932c5..6da7858830 100644 --- a/legacy/eina/src/tests/.cvsignore +++ b/legacy/eina/src/tests/.cvsignore @@ -6,3 +6,4 @@ Makefile .libs .deps eina_suite +eina_bench diff --git a/legacy/eina/src/tests/Makefile.am b/legacy/eina/src/tests/Makefile.am index ae86f33fb1..aa04ec5b8b 100644 --- a/legacy/eina/src/tests/Makefile.am +++ b/legacy/eina/src/tests/Makefile.am @@ -1,11 +1,12 @@ MAINTAINERCLEANFILES = Makefile.in +benchdir = $(bindir) + AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/include \ @CHECK_CFLAGS@ - if EINA_ENABLE_TESTS check_PROGRAMS = eina_suite @@ -17,12 +18,26 @@ eina_test_array.c \ eina_test_error.c \ eina_test_magic.c \ eina_test_inlist.c \ -eina_test_lalloc.c +eina_test_main.c \ +eina_test_counter.c \ +eina_test_lalloc.c \ +eina_test_hash.c eina_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeina.la -EXTRA_DIST = eina_suite.h +endif + +if EINA_ENABLE_BENCH + +bench_PROGRAMS = eina_bench + +eina_bench_SOURCES = \ +eina_bench.c \ +eina_bench_hash.c + +eina_bench_LDADD = $(top_builddir)/src/lib/libeina.la endif +EXTRA_DIST = eina_bench.h eina_suite.h diff --git a/legacy/eina/src/tests/eina_bench.c b/legacy/eina/src/tests/eina_bench.c new file mode 100644 index 0000000000..b597acb46d --- /dev/null +++ b/legacy/eina/src/tests/eina_bench.c @@ -0,0 +1,185 @@ +#include +#include +#include + +#include "eina_bench.h" +#include "eina_inlist.h" +#include "eina_counter.h" + +typedef struct _Eina_Run Eina_Run; +struct _Eina_Run +{ + Eina_Inlist __list; + + Eina_Bench_Specimens cb; + const char *name; + int start; + int end; + int step; +}; + +struct _Eina_Bench +{ + const char *name; + const char *run; + + Eina_Inlist *runs; +}; + +Eina_Bench * +eina_bench_new(const char *name, const char *run) +{ + Eina_Bench *new; + + new = calloc(1, sizeof (Eina_Bench)); + if (!new) return NULL; + + new->name = name; + new->run = run; + + return new; +} + +void +eina_bench_delete(Eina_Bench *bench) +{ + if (!bench) return ; + + while (bench->runs) + { + Eina_Run *run = (Eina_Run *) bench->runs; + + bench->runs = eina_inlist_remove(bench->runs, bench->runs); + free(run); + } + + free(bench); +} + +void +eina_bench_register(Eina_Bench *bench, const char *name, Eina_Bench_Specimens bench_cb, + int count_start, int count_end, int count_step) +{ + Eina_Run *run; + + if (!bench) return ; + + run = calloc(1, sizeof (Eina_Run)); + if (!run) return ; + + run->cb = bench_cb; + run->name = name; + run->start = count_start; + run->end = count_end; + run->step = count_step; + + bench->runs = eina_inlist_append(bench->runs, run); +} + +void +eina_bench_run(Eina_Bench *bench) +{ + FILE *main_script; + FILE *current_data; + Eina_Run *run; + char buffer[PATH_MAX]; + Eina_Bool first = EINA_FALSE; + + if (!bench) return ; + + snprintf(buffer, PATH_MAX, "bench_%s_%s.gnuplot", bench->name, bench->run); + + main_script = fopen(buffer, "w"); + if (!main_script) return ; + + fprintf(main_script, + "set autoscale # scale axes automatically\n" + "unset log # remove any log-scaling\n" + "unset label # remove any previous labels\n" + "set xtic auto # set xtics automatically\n" + "set ytic auto # set ytics automatically\n" + "set logscale y\n" + "set terminal png size 1024,768\n" + "set output \"output_%s_%s.png\"\n" + "set title \"%s %s\n" + "set xlabel \"tests\"\n" + "set ylabel \"time\"\n" + "plot ", bench->name, bench->run, bench->name, bench->run); + + eina_counter_init(); + + EINA_INLIST_ITER_NEXT(bench->runs, run) + { + Eina_Counter *counter; + int i; + + snprintf(buffer, PATH_MAX, "bench_%s_%s.%s.data", bench->name, bench->run, run->name); + + current_data = fopen(buffer, "w"); + if (!current_data) continue ; + + counter = eina_counter_add(run->name); + + for (i = run->start; i < run->end; i += run->step) + { + fprintf(stderr, "Run %s: %i\n", run->name, i); + eina_counter_start(counter); + + run->cb(i); + + eina_counter_stop(counter, i); + } + + eina_counter_dump(counter, current_data); + + eina_counter_delete(counter); + + fclose(current_data); + + if (first == EINA_FALSE) first = EINA_TRUE; + else fprintf(main_script, ", \\\n"); + + fprintf(main_script, + "\"%s\" using 1:2 title \'%s\' with points", + buffer, run->name); + } + + fprintf(main_script, "\n"); + + eina_counter_shutdown(); + + fclose(main_script); +} + +typedef struct _Eina_Bench_Case Eina_Bench_Case; +struct _Eina_Bench_Case +{ + const char *bench_case; + void (*build)(Eina_Bench *bench); +}; + +static const Eina_Bench_Case etc[] = { + { "Hash", eina_bench_hash }, + { NULL, NULL } +}; + +int +main(int argc, char **argv) +{ + Eina_Bench *test; + int i; + + if (argc != 2) return -1; + + for (i = 0; etc[i].bench_case != NULL; ++i) + { + test = eina_bench_new(etc[i].bench_case, argv[1]); + if (!test) continue ; + + etc[i].build(test); + + eina_bench_run(test); + + eina_bench_delete(test); + } +} diff --git a/legacy/eina/src/tests/eina_bench.h b/legacy/eina/src/tests/eina_bench.h new file mode 100644 index 0000000000..0bac209a0a --- /dev/null +++ b/legacy/eina/src/tests/eina_bench.h @@ -0,0 +1,13 @@ +#ifndef EINA_BENCH_H_ +#define EINA_BENCH_H_ + +typedef struct _Eina_Bench Eina_Bench; +typedef void (*Eina_Bench_Specimens)(int request); +#define EINA_BENCH(Function) ((Eina_Bench_Specimens)Function) + +void eina_bench_register(Eina_Bench *bench, const char *name, Eina_Bench_Specimens bench_cb, + int count_start, int count_end, int count_set); + +void eina_bench_hash(Eina_Bench *bench); + +#endif diff --git a/legacy/eina/src/tests/eina_bench_hash.c b/legacy/eina/src/tests/eina_bench_hash.c new file mode 100644 index 0000000000..2dce462b3d --- /dev/null +++ b/legacy/eina/src/tests/eina_bench_hash.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include + +#include "eina_hash.h" +#include "eina_array.h" +#include "eina_bench.h" + +static void +eina_bench_insert_superfast(int request) +{ + Eina_Hash *hash = NULL; + Eina_Array *array = NULL; + int *tmp_val; + unsigned int i; + + array = eina_array_new(1000); + + hash = eina_hash_string_superfast_new(); + + for (i = 0; i < (unsigned int) request; ++i) + { + char *tmp_key = malloc(10); + + tmp_val = malloc(sizeof (int)); + + if (!tmp_key || !tmp_val) continue ; + + snprintf(tmp_key, 10, "%i", i); + *tmp_val = i; + + eina_hash_add(hash, tmp_key, tmp_val); + + eina_array_append(array, tmp_val); + + free(tmp_key); + } + + eina_hash_free(hash); + + EINA_ARRAY_ITER_NEXT(array, i, tmp_val) + free(tmp_val); + + eina_array_free(array); +} + +static void +eina_bench_insert_djb2(int request) +{ + Eina_Hash *hash = NULL; + Eina_Array *array = NULL; + int *tmp_val; + unsigned int i; + + array = eina_array_new(1000); + + hash = eina_hash_string_djb2_new(); + + for (i = 0; i < (unsigned int) request; ++i) + { + char *tmp_key = malloc(10); + + tmp_val = malloc(sizeof (int)); + + if (!tmp_key || !tmp_val) continue ; + + snprintf(tmp_key, 10, "%i", i); + *tmp_val = i; + + eina_hash_add(hash, tmp_key, tmp_val); + + eina_array_append(array, tmp_val); + + free(tmp_key); + } + + eina_hash_free(hash); + + EINA_ARRAY_ITER_NEXT(array, i, tmp_val) + free(tmp_val); + + eina_array_free(array); +} + +static void +eina_bench_lookup_superfast(int request) +{ + Eina_Hash *hash = NULL; + Eina_Array *array = NULL; + int *tmp_val; + unsigned int i; + + array = eina_array_new(1000); + + hash = eina_hash_string_superfast_new(); + + for (i = 0; i < (unsigned int) request; ++i) + { + char tmp_key[10]; + + tmp_val = malloc(sizeof (int)); + + if (!tmp_val) continue ; + + snprintf(tmp_key, 10, "%i", i); + *tmp_val = i; + + eina_hash_add(hash, tmp_key, tmp_val); + + eina_array_append(array, tmp_val); + } + + srand(time(NULL)); + + for (i = 0; i < (unsigned int) request; ++i) + { + char tmp_key[10]; + + snprintf(tmp_key, 10, "%i", rand() % request); + + tmp_val = eina_hash_find(hash, tmp_key); + } + + eina_hash_free(hash); + + EINA_ARRAY_ITER_NEXT(array, i, tmp_val) + free(tmp_val); + + eina_array_free(array); +} + +static void +eina_bench_lookup_djb2(int request) +{ + Eina_Hash *hash = NULL; + Eina_Array *array = NULL; + int *tmp_val; + unsigned int i; + + array = eina_array_new(1000); + + hash = eina_hash_string_djb2_new(); + + for (i = 0; i < (unsigned int) request; ++i) + { + char *tmp_key = malloc(10); + + tmp_val = malloc(sizeof (int)); + + if (!tmp_key || !tmp_val) continue ; + + snprintf(tmp_key, 10, "%i", i); + *tmp_val = i; + + eina_hash_add(hash, tmp_key, tmp_val); + + eina_array_append(array, tmp_val); + + free(tmp_key); + } + + srand(time(NULL)); + + for (i = 0; i < (unsigned int) request; ++i) + { + char tmp_key[10]; + + snprintf(tmp_key, 10, "%i", rand() % request); + + tmp_val = eina_hash_find(hash, tmp_key); + } + + eina_hash_free(hash); + + EINA_ARRAY_ITER_NEXT(array, i, tmp_val) + free(tmp_val); + + eina_array_free(array); +} + +void eina_bench_hash(Eina_Bench *bench) +{ + eina_bench_register(bench, "superfast-insert", EINA_BENCH(eina_bench_insert_superfast), 1000, 180000, 2500); + eina_bench_register(bench, "djb2-insert", EINA_BENCH(eina_bench_insert_djb2), 1000, 180000, 2500); + eina_bench_register(bench, "superfast-lookup", EINA_BENCH(eina_bench_lookup_superfast), 1000, 180000, 2500); + eina_bench_register(bench, "djb2-lookup", EINA_BENCH(eina_bench_lookup_djb2), 1000, 180000, 2500); +}