From 3dccd4484e76e3cac9e0367589bb4ca25e5ee46d Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Fri, 30 Mar 2018 21:35:19 +0200 Subject: [PATCH] Add nedtries --- README.md | 1 + bench/Makefile | 11 +++-- bench/bench-nedtries.c | 101 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 bench/bench-nedtries.c diff --git a/README.md b/README.md index 33d6ea7d..73167d78 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,7 @@ For example: * [libdict](https://github.com/fmela/libdict) * [libgenerics](https://github.com/yudi-matsuzake/libgenerics) * [ctemplates](https://github.com/farhiongit/Ctemplates) +* [nedtries](https://github.com/ned14/nedtries) Each of theses can be classified into one of the following concept: diff --git a/bench/Makefile b/bench/Makefile index 4e67e32b..a3366e1e 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -231,7 +231,6 @@ bench-libsrt0: # The library shall be built. bench-liblfds: @if test -n "$${LIBLFDS}" ; then $(MAKE) bench-liblfds0 ; else echo "Nothing to be done for LIBLFDS." ; fi - bench-liblfds0: $(CC) $(CFLAGS) $(CPPFLAGS) -I "$${LIBLFDS}/inc" -Wno-unknown-pragmas bench-liblfds.c -o bench-liblfds.exe $${LIBLFDS}/bin/liblfds711.so -lpthread @LD_LIBRARY_PATH="$${LIBLFDS}/bin:$${LD_LIBRARY_PATH}" ./bench-liblfds.exe 60 @@ -241,7 +240,6 @@ bench-liblfds0: # The library shall be built. bench-concurrentqueue: @if test -n "$${CONCURRENTQUEUE}" ; then $(MAKE) bench-concurrentqueue0 ; else echo "Nothing to be done for CONCURRENTQUEUE." ; fi - bench-concurrentqueue0: $(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${CONCURRENTQUEUE}/" bench-concurrentqueue.cpp -o bench-concurrentqueue.exe -lpthread @./bench-concurrentqueue.exe 60 @@ -250,7 +248,6 @@ bench-concurrentqueue0: # XXHASH shall point to the source directory of xxhash bench-xxhash: @if test -n "$${XXHASH}" ; then $(MAKE) bench-xxhash0 ; else echo "Nothing to be done for XXHASH." ; fi - bench-xxhash0: $(CC) $(CFLAGS) $(CPPFLAGS) -I "$${XXHASH}/" bench-xxhash.c "$${XXHASH}/libxxhash.a" -o bench-xxhash.exe @./bench-xxhash.exe 70 @@ -262,6 +259,14 @@ bench-boost0: $(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${BOOST}" bench-boost.cpp -o bench-boost.exe -lpthread @./bench-boost.exe 60 +# NEDTRIES shall point to the header location. +bench-nedtries: + @if test -n "$${NEDTRIES}" ; then $(MAKE) bench-nedtries0 ; else echo "Nothing to be done for NEDTRIES." ; fi +bench-nedtries0: + $(CC) $(CFLAGS) $(CPPFLAGS) -I "$${NEDTRIES}" bench-nedtries.c -o bench-nedtries.exe + @./bench-nedtries.exe 40 + @./bench-nedtries.exe 45 + ############################################################################ bench-plain: diff --git a/bench/bench-nedtries.c b/bench/bench-nedtries.c new file mode 100644 index 00000000..03e62942 --- /dev/null +++ b/bench/bench-nedtries.c @@ -0,0 +1,101 @@ +#define NDEBUG +#include +#include +#include +#include + +#include "nedtrie.h" + +#include "common.h" + +/********************************************************************************************/ + +typedef struct foo_s { + NEDTRIE_ENTRY(foo_s) link; + unsigned long key; + unsigned long value; +} foo_t; +typedef struct foo_tree_s foo_tree_t; +NEDTRIE_HEAD(foo_tree_s, foo_s); + +static inline size_t fookeyfunct(const foo_t *r) +{ + return r->key; +} + +NEDTRIE_GENERATE(static, foo_tree_s, foo_s, link, fookeyfunct, NEDTRIE_NOBBLEZEROS(foo_tree_s)) + +static void +test_dict(unsigned long n) +{ + foo_tree_t footree; + NEDTRIE_INIT(&footree); + + for (size_t i = 0; i < n; i++) { + unsigned long key = rand_get(); + unsigned long val = rand_get(); + foo_t * p = malloc(sizeof(foo_t)); + if (p == NULL) abort(); + p->key = key; + p->value = val; + NEDTRIE_INSERT(foo_tree_s, &footree, p); + } + rand_init(); + unsigned int s = 0; + for (size_t i = 0; i < n; i++) { + foo_t key = { .key = rand_get() }; + foo_t *p = NEDTRIE_FIND(foo_tree_s, &footree, &key); + if (p) + s += p->value; + } + g_result = s; + foo_t *r, *next; + NEDTRIE_FOREACH_SAFE(r, foo_tree_s, &footree, next) { + // Remove is needed, otherwise it segfault + NEDTRIE_REMOVE(foo_tree_s, &footree, r); + free(r); + } +} + +static void +test_dict_noalloc(unsigned long n) +{ + foo_tree_t footree; + NEDTRIE_INIT(&footree); + + foo_t *tab = malloc(n*sizeof(foo_t)); + if (tab == NULL) abort(); + + for (size_t i = 0; i < n; i++) { + unsigned long key = rand_get(); + unsigned long val = rand_get(); + tab[i].key = key; + tab[i].value = val; + NEDTRIE_INSERT(foo_tree_s, &footree, &tab[i]); + } + rand_init(); + unsigned int s = 0; + for (size_t i = 0; i < n; i++) { + foo_t key = { .key = rand_get() }; + foo_t *p = NEDTRIE_FIND(foo_tree_s, &footree, &key); + if (p) + s += p->value; + } + g_result = s; + free(tab); +} + +/********************************************************************************************/ + + +int main(int argc, const char *argv[]) +{ + int n = (argc > 1) ? atoi(argv[1]) : 0; + if (n == 40) + test_function("Dict time", 1000000, test_dict); + if (n == 45) + test_function("Dict No Alloc time", 1000000, test_dict_noalloc); + + exit(0); +} +