diff --git a/bench/Makefile b/bench/Makefile index 838fd09f..31ac6c67 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -143,6 +143,19 @@ bench-hopscotchmap0: @./bench-hopscotchmap.exe 42 @./bench-hopscotchmap.exe 43 +# UTHASH shall point to the directory where the source are +bench-uthash: + if test -n "$${UTHASH}" ; then make bench-uthash0 ; else echo "Nothing to be done." ; fi + +bench-uthash0: + $(CC) $(CFLAGS) $(CPPFLAGS) -I "$${UTHASH}" bench-uthash.c -o bench-uthash.exe + @./bench-uthash.exe 10 + @./bench-uthash.exe 20 + @./bench-uthash.exe 41 + @./bench-uthash.exe 42 + @./bench-uthash.exe 43 + @./bench-uthash.exe 50 + ############################################################################ bench-plain: diff --git a/bench/bench-uthash.c b/bench/bench-uthash.c new file mode 100644 index 00000000..ece00b98 --- /dev/null +++ b/bench/bench-uthash.c @@ -0,0 +1,220 @@ +#define NDEBUG + +#include +#include +#include +#include +#include +#include +#include + +#include "include/uthash.h" +#include "include/utarray.h" +#include "include/utlist.h" + +#include "common.h" + +/********************************************************************************************/ + +static const UT_icd int_icd = { + .sz = sizeof (unsigned int), + .init = NULL, + .dtor = NULL, + .copy = NULL +}; + +static void test_array(size_t n) +{ + UT_array a1, a2; + + utarray_init(&a1, &int_icd); + utarray_init(&a2, &int_icd); + + for(size_t i = 0; i < n; i++) { + unsigned int v1 = rand_get(), v2 = rand_get(); + utarray_push_back(&a1, &v1); + utarray_push_back(&a2, &v2); + } + unsigned int s = 0; + for(unsigned long i = 0; i < n; i++) { + s += *(unsigned long *) utarray_eltptr(&a1, i ) * *(unsigned long *)utarray_eltptr(&a2, i ); + } + g_result = s; + + utarray_done(&a1); + utarray_done(&a2); +} + +/********************************************************************************************/ + +struct list_node_s { + unsigned int value; + struct list_node_s *next; +}; + +static void test_list (size_t n) +{ + struct list_node_s *a1 = NULL, *a2 = NULL; + + for(size_t i = 0; i < n; i++) { + struct list_node_s *p = malloc(sizeof(struct list_node_s)); + if (!p) abort(); + p->value = rand_get(); + LL_PREPEND(a1, p); + p = malloc(sizeof(struct list_node_s)); + if (!p) abort(); + p->value = rand_get(); + LL_PREPEND(a2, p); + } + unsigned int s = 0; + for(struct list_node_s *it1 = a1, *it2 = a2 + ; it1 != NULL + ; it1 = it1->next, it2 = it2->next) { + s += it1->value * it2->value; + } + g_result = s; + + struct list_node_s *el; + LL_FOREACH(a1, el) free(el); + LL_FOREACH(a2, el) free(el); +} + +/********************************************************************************************/ + +struct hash_i_node_s { + unsigned long key; + unsigned long value; + UT_hash_handle hh; +}; + +static void +test_dict(unsigned long n) +{ + struct hash_i_node_s *dict = NULL; + + for (size_t i = 0; i < n; i++) { + unsigned long k = rand_get(); + struct hash_i_node_s *s; + HASH_FIND(hh, dict, &k, sizeof (unsigned long), s); + if (s == NULL) { + s = malloc(sizeof(struct hash_i_node_s)); + if (!s) abort(); + s->key = k; + s->value = rand_get(); + HASH_ADD(hh, dict, key, sizeof(unsigned long), s); + } + } + rand_init(); + unsigned int s = 0; + for (size_t i = 0; i < n; i++) { + unsigned long k = rand_get(); + struct hash_i_node_s *sp; + HASH_FIND(hh, dict, &k, sizeof (unsigned long), sp); + if (sp != NULL) + s += sp->value; + } + g_result = s; + struct hash_i_node_s *current, *tmp; + HASH_ITER(hh, dict, current, tmp) { + HASH_DEL(dict,current); /* delete it (users advances to next) */ + free(current); /* free it */ + } +} + +/********************************************************************************************/ + +typedef struct { + char a[256]; +} char_array_t; + +struct hash_b_node_s { + char_array_t key; + char_array_t value; + UT_hash_handle hh; +}; + +static void +test_dict_big(unsigned long n) +{ + struct hash_b_node_s *dict = NULL; + + for (size_t i = 0; i < n; i++) { + char_array_t k; + sprintf(k.a, "%u", rand_get()); + struct hash_b_node_s *s; + HASH_FIND(hh, dict, &k, sizeof (char_array_t), s); + if (s == NULL) { + s = malloc(sizeof(struct hash_b_node_s)); + if (!s) abort(); + memcpy(s->key.a, k.a, sizeof(s->key)); + sprintf(s->value.a, "%u", rand_get()); + HASH_ADD(hh, dict, key, sizeof(char_array_t), s); + } + } + rand_init(); + unsigned int s = 0; + for (size_t i = 0; i < n; i++) { + char_array_t k; + sprintf(k.a, "%u", rand_get()); + struct hash_b_node_s *sp; + HASH_FIND(hh, dict, &k, sizeof (char_array_t), sp); + if (sp != NULL) + s ++; + } + g_result = s; + + struct hash_b_node_s *current, *tmp; + HASH_ITER(hh, dict, current, tmp) { + HASH_DEL(dict,current); /* delete it (users advances to next) */ + free(current); /* free it */ + } +} + +/********************************************************************************************/ + +static const UT_icd float_icd = { + .sz = sizeof (float), + .init = NULL, + .dtor = NULL, + .copy = NULL +}; + +static int cmp(const void *a1, const void *a2) +{ + const float *f1 = a1; + const float *f2 = a2; + return (*f1 < *f2) ? -1 : (*f1 > *f2); +} + +static void test_sort(size_t n) +{ + UT_array a1; + + utarray_init(&a1, &float_icd); + for(size_t i = 0; i < n; i++) { + float v1 = rand_get(); + utarray_push_back(&a1, &v1); + } + utarray_sort(&a1, cmp); + g_result = *(float *)utarray_eltptr(&a1, 0); + utarray_done(&a1); +} + +/********************************************************************************************/ + +int main(int argc, const char *argv[]) +{ + int n = (argc > 1) ? atoi(argv[1]): 0; + if (n == 10) + test_function("List time",10000000, test_list); + if (n == 20) + test_function("Array time", 100000000, test_array); + if (n == 40 || n == 42) + test_function("Dict time", 1000000, test_dict); + if (n == 41) + test_function("DictB time", 1000000, test_dict_big); + if (n == 50) + test_function("Sort time", 10000000, test_sort); + exit(0); +} +