From 468b7e7a0c6190d6509cbebd0e8694f170443786 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Wed, 10 Jun 2020 22:29:59 +0200 Subject: [PATCH] Add bench for CMC --- bench/Makefile | 14 ++- bench/bench-cmc.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 bench/bench-cmc.c diff --git a/bench/Makefile b/bench/Makefile index 7498d993..6a6a1cf7 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -7,7 +7,7 @@ N=4 BENCH_DEF= RM=rm -rf -.PHONY: all pgo container queue mempool string plain bench-mlib bench-mlib-mempool bench-stl bench-qt bench-glib bench-klib bench-libdynamic bench-sparsepp bench-collectionc bench-tommyds bench-flathashmap bench-emilib bench-hopscotchmap bench-mlib-thread bench-liblfds bench-concurrentqueue bench-boost bench-mempool bench-string bench-plain bench-rigtorp-mpmc-queue +.PHONY: all pgo container queue mempool string plain bench-mlib bench-mlib-mempool bench-stl bench-qt bench-glib bench-klib bench-libdynamic bench-sparsepp bench-collectionc bench-tommyds bench-flathashmap bench-emilib bench-hopscotchmap bench-mlib-thread bench-liblfds bench-concurrentqueue bench-boost bench-mempool bench-string bench-plain bench-rigtorp-mpmc-queue bench-cmc all: container queue mempool string plain @@ -17,7 +17,7 @@ pgo: ######################################################################### -container: bench-mlib bench-mlib-mempool bench-stl bench-qt bench-glib bench-klib bench-libdynamic bench-sparsepp bench-densehashmap bench-collectionc bench-tommyds bench-flathashmap bench-emilib bench-hopscotchmap bench-uthash bench-qlibc bench-libsrt bench-nedtries bench-rigtorp-hashmap +container: bench-mlib bench-mlib-mempool bench-stl bench-qt bench-glib bench-klib bench-libdynamic bench-cmc bench-sparsepp bench-densehashmap bench-collectionc bench-tommyds bench-flathashmap bench-emilib bench-hopscotchmap bench-uthash bench-qlibc bench-libsrt bench-nedtries bench-rigtorp-hashmap @echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" queue: bench-mlib-thread bench-liblfds bench-concurrentqueue bench-boost bench-rigtorp-mpmc-queue @@ -130,6 +130,16 @@ bench-klib0: @./bench-klib.exe 41 @./bench-klib.exe 50 +# CMC shall point to the directory where the CMC main header is +bench-cmc: + @if test -n "$${CMC}" ; then $(MAKE) bench-cmc0 ; else echo "Nothing to be done for CMC." ; fi + +bench-cmc0: + $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${CMC} bench-cmc.c common.c -o bench-cmc.exe + @./bench-cmc.exe 20 + @./bench-cmc.exe 30 + @./bench-cmc.exe 40 + # LIBDYNAMIC shall point to the the directory containing the file libdynamic.pc bench-libdynamic: @if test -n "$${LIBDYNAMIC}" ; then $(MAKE) bench-libdynamic0 ; else echo "Nothing to be done for LIBDYNAMIC." ; fi diff --git a/bench/bench-cmc.c b/bench/bench-cmc.c new file mode 100644 index 00000000..fb87adf1 --- /dev/null +++ b/bench/bench-cmc.c @@ -0,0 +1,227 @@ +#define NDEBUG + +#include +#include +#include + +#include "cmc/list.h" +#include "cmc/treemap.h" +#include "cmc/hashmap.h" + +#include "common.h" + +/********************************************************************************************/ + +// CMC list are dynamic array +CMC_GENERATE_LIST(list_uint, list_uint_s, unsigned int) + +struct list_uint_s_fval list_fval = { .cmp = NULL, + .cpy = NULL, + .str = NULL, + .free = NULL, + .hash = NULL, + .pri = NULL }; + +static void test_array(size_t n) +{ + struct list_uint_s *a1 = list_uint_new(1, &list_fval); + struct list_uint_s *a2 = list_uint_new(1, &list_fval); + + for(size_t i = 0; i < n; i++) { + list_uint_push_back(a1, rand_get() ); + list_uint_push_back(a2, rand_get() ); + } + + unsigned int s = 0; + for(unsigned long i = 0; i < n; i++) { + s += list_uint_get(a1, i ) * list_uint_get(a2, i ); + } + g_result = s; + + list_uint_free(a1); + list_uint_free(a2); +} + +/********************************************************************************************/ + +#define my_cmp(a,b) ( (a) < (b) ? -1 : (a) > (b) ) + +CMC_GENERATE_TREEMAP(tree_ulong, tree_ulong_s, unsigned long, bool) + +int cmp_ulong(unsigned long a, unsigned long b) { return my_cmp(a,b); } + +struct tree_ulong_s_fkey tree_fkey = { .cmp = cmp_ulong, + .cpy = NULL, + .str = NULL, + .free = NULL, + .hash = NULL, + .pri = NULL }; + +struct tree_ulong_s_fval tree_fval = { .cmp = NULL, + .cpy = NULL, + .str = NULL, + .free = NULL, + .hash = NULL, + .pri = NULL }; + +static void test_rbtree(size_t n) +{ + struct tree_ulong_s *tree; + tree = tree_ulong_new(&tree_fkey, &tree_fval); + + for (size_t i = 0; i < n; i++) { + unsigned long j = rand_get(); + tree_ulong_insert(tree, j, true); + } + + rand_init(); + unsigned int s = 0; + for (size_t i = 0; i < n; i++) { + unsigned long j = rand_get(); + if (tree_ulong_get_ref(tree, j) != 0) + s+= j; + } + g_result = s; + tree_ulong_free(tree); +} + +/********************************************************************************************/ + +#define hash_func(a) kh_int64_hash_func(a) +size_t hash_ulong(unsigned long a) +{ + return ( (a) >> 33 ) ^ (a) ^ ((a) << 11); +} + +CMC_GENERATE_HASHMAP(hmap, hmap_s, unsigned long, unsigned long) + +struct hmap_s_fkey hmap_fkey = { .cmp = cmp_ulong, + .cpy = NULL, + .str = NULL, + .free = NULL, + .hash = hash_ulong, + .pri = NULL }; + +struct hmap_s_fval hmap_fval = { .cmp = NULL, + .cpy = NULL, + .str = NULL, + .free = NULL, + .hash = NULL, + .pri = NULL }; + +static void +test_dict(size_t n) +{ + struct hmap_s *dict = hmap_new(16, 0.7, &hmap_fkey, &hmap_fval); + + for (size_t i = 0; i < n; i++) { + hmap_insert(dict, rand_get(), rand_get()); + } + rand_init(); + unsigned int s = 0; + for (size_t i = 0; i < n; i++) { + unsigned long *val = hmap_get_ref(dict, rand_get()); + if (val != 0) + s += *val; + } + g_result = s; + + hmap_free(dict); +} + +/********************************************************************************************/ + +#if 0 // Not working issue in using not integer types + +typedef struct { + char a[256]; +} char_array_t; +static inline int char_cmp (const char_array_t a, const char_array_t b) { return strcmp(a.a,b.a); } +static inline size_t char_hash(const char_array_t a) { + size_t hash = 0; + const char *s = a.a; + while (*s) hash = hash * 31421 + (*s++) + 6927; + return hash; +} + +CMC_GENERATE_HASHMAP(bhmap, bhmap_s, char_array_t, char_array_t) + +struct bhmap_s_fkey bhmap_fkey = { .cmp = char_cmp, + .cpy = NULL, + .str = NULL, + .free = NULL, + .hash = char_hash, + .pri = NULL }; + +struct bhmap_s_fval bhmap_fval = { .cmp = NULL, + .cpy = NULL, + .str = NULL, + .free = NULL, + .hash = NULL, + .pri = NULL }; + +static void +test_dict_big(size_t n) +{ + struct bhmap_s *dict = bhmap_new(16, 0.7, &bhmap_fkey, &bhmap_fval); + + for (size_t i = 0; i < n; i++) { + char_array_t s1, s2; + sprintf(s1.a, "%u", rand_get()); + sprintf(s2.a, "%u", rand_get()); + bhmap_insert(dict, s1, s2); + } + rand_init(); + unsigned int s = 0; + for (size_t i = 0; i < n; i++) { + char_array_t s1; + sprintf(s1.a, "%u", rand_get() ); + char_array_t *val = bhmap_get_ref(dict, s1); + if (val != 0) + s ++; + } + g_result = s; + + bhmap_free(dict); +} +#endif + +/********************************************************************************************/ +#if 0 + +// NOTE: Needed for compiling +double drand48(void) { return rand_get(); } + +KSORT_INIT_GENERIC(float) + +static void test_sort(size_t n) +{ + kvec_t(float) a1; + + kv_init(a1); + for(size_t i = 0; i < n; i++) { + kv_push(float, a1, rand_get() ); + } + // NOTE: Is-it the right way to do? Seems very low level! + ks_introsort_float(n, & kv_A(a1, 0)); + g_result = kv_A(a1, 0); + kv_destroy(a1); +} + +#endif + +/********************************************************************************************/ + +const config_func_t table[] = { + { 20, "Array", 100000000, 0, test_array, 0}, + { 30, "Rbtree", 1000000, 0, test_rbtree, 0}, + { 40, "dict", 1000000, 0, test_dict, 0}, + //{ 41, "dictBig", 1000000, 0, test_dict_big, 0}, +}; + +int main(int argc, const char *argv[]) +{ + test("CMC", numberof(table), table, argc, argv); + exit(0); +} +