diff --git a/bench/Makefile b/bench/Makefile deleted file mode 100644 index 3e3a3519..00000000 --- a/bench/Makefile +++ /dev/null @@ -1,512 +0,0 @@ -# Copyright (c) 2017-2024, Patrick Pelissier -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# + Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# + Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -CC=cc -std=c11 -CXX=c++ -std=c++11 -CFLAGS=-O2 -march=native -Wall -XCFLAGS= -CPPFLAGS=-I.. -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-emhash 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 - -pgo: - $(MAKE) all XCFLAGS="-fprofile-generate=pgo" - $(MAKE) all XCFLAGS="-fprofile-use=pgo" - -######################################################################### - -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-emhash bench-hopscotchmap bench-uthash bench-qlibc bench-libsrt bench-nedtries bench-rigtorp-hashmap bench-ctl bench-stc bench-pottery bench-CC - @echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" - -queue: bench-mlib-thread bench-liblfds bench-concurrentqueue bench-boost bench-rigtorp-mpmc-queue - @echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" - -mempool: bench-mempool - @echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" - -string: bench-string - @echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" - -plain: bench-plain - @echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" - - - -######################################################################### - - -bench-mlib: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -pthread bench-mlib.c common.c -o bench-mlib.exe - @./bench-mlib.exe 10 - @./bench-mlib.exe 11 - @./bench-mlib.exe 20 - @./bench-mlib.exe 30 - @./bench-mlib.exe 31 - @./bench-mlib.exe 40 - @./bench-mlib.exe 41 - @./bench-mlib.exe 42 - @./bench-mlib.exe 46 - @./bench-mlib.exe 47 - @./bench-mlib.exe 43 - @./bench-mlib.exe 50 - @./bench-mlib.exe 51 - -bench-mlib-mempool: - $(CC) $(CFLAGS) $(CPPFLAGS) bench-mlib.c common.c -DUSE_MEMPOOL -pthread -o bench-mlib-mempool.exe - @./bench-mlib-mempool.exe 10 - @./bench-mlib-mempool.exe 11 - @./bench-mlib-mempool.exe 20 - @./bench-mlib-mempool.exe 30 - @./bench-mlib-mempool.exe 31 - @./bench-mlib-mempool.exe 40 - @./bench-mlib-mempool.exe 41 - @./bench-mlib-mempool.exe 42 - @./bench-mlib-mempool.exe 46 - @./bench-mlib-mempool.exe 47 - @./bench-mlib-mempool.exe 43 - @./bench-mlib-mempool.exe 50 - @./bench-mlib-mempool.exe 51 - -bench-mlib-thread: - $(CC) $(CFLAGS) $(CPPFLAGS) bench-mlib.c common.c -DMULTI_THREAD_MEASURE -pthread -o bench-mlib-thread.exe - @./bench-mlib-thread.exe 60 - @./bench-mlib-thread.exe 61 - @./bench-mlib-thread.exe 62 - @./bench-mlib-thread.exe 63 - @./bench-mlib-thread.exe 64 - @./bench-mlib-thread.exe 65 - @./bench-mlib-thread.exe 66 - -bench-stl: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) bench-stl.cpp common.c -o bench-stl.exe - @./bench-stl.exe 10 - @./bench-stl.exe 20 - @./bench-stl.exe 30 - @./bench-stl.exe 40 - @./bench-stl.exe 41 - @./bench-stl.exe 42 - @./bench-stl.exe 46 - @./bench-stl.exe 43 - @./bench-stl.exe 50 - @./bench-stl.exe 51 - -# QT shall point to the the directory containing the file .pc are stored -bench-qt: - @if test -n "$${QT}" ; then $(MAKE) bench-qt0 ; else echo "Nothing to be done for QT." ; fi -bench-qt0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -fPIC bench-qt.cpp common.c -o bench-qt.exe `PKG_CONFIG_PATH="$${QT}" pkg-config --libs --cflags Qt5Core` - @./bench-qt.exe 10 - @./bench-qt.exe 20 - @./bench-qt.exe 30 - @./bench-qt.exe 40 - @./bench-qt.exe 41 - @./bench-qt.exe 42 - @./bench-qt.exe 50 - -# GLIB shall point to the the directory containing the file .pc are stored -bench-glib: - @if test -n "$${GLIB}" ; then $(MAKE) bench-glib0 ; else echo "Nothing to be done for GLIB." ; fi -bench-glib0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) bench-glib.c common.c -o bench-glib.exe `PKG_CONFIG_PATH="$${GLIB}" pkg-config --libs --cflags glib-2.0` - @./bench-glib.exe 10 - @./bench-glib.exe 20 - @./bench-glib.exe 30 - @./bench-glib.exe 40 - @./bench-glib.exe 41 - @./bench-glib.exe 50 - -# KLIB shall point to the directory where the headers are -bench-klib: - @if test -n "$${KLIB}" ; then $(MAKE) bench-klib0 ; else echo "Nothing to be done for KLIB." ; fi - -bench-klib0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${KLIB} bench-klib.c common.c -o bench-klib.exe - @./bench-klib.exe 10 - @./bench-klib.exe 20 - @./bench-klib.exe 30 - @./bench-klib.exe 40 - @./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 source directory where the source is built -bench-libdynamic: - @if test -n "$${LIBDYNAMIC}" ; then $(MAKE) bench-libdynamic0 ; else echo "Nothing to be done for LIBDYNAMIC." ; fi - -bench-libdynamic0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) bench-libdynamic.c common.c -o bench-libdynamic.exe -I$${LIBDYNAMIC}/src $${LIBDYNAMIC}/.libs/libdynamic.a - @./bench-libdynamic.exe 20 - @./bench-libdynamic.exe 40 - @./bench-libdynamic.exe 41 - -# SPARSEPP shall point to the directory where the headers are -bench-sparsepp: - @if test -n "$${SPARSEPP}" ; then $(MAKE) bench-sparsepp0 ; else echo "Nothing to be done for SPARSEPP." ; fi - -bench-sparsepp0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${SPARSEPP}" -I "$${SPARSEPP}/.." bench-sparsepp.cpp common.c -o bench-sparsepp.exe - @./bench-sparsepp.exe 41 - @./bench-sparsepp.exe 42 - @./bench-sparsepp.exe 43 - -# DENSEHASHMAP shall point to the directory where the src are -bench-densehashmap: - @if test -n "$${DENSEHASHMAP}" ; then $(MAKE) bench-densehashmap0 ; else echo "Nothing to be done Google DENSEHASHMAP." ; fi - -bench-densehashmap0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${DENSEHASHMAP}" -I "$${DENSEHASHMAP}/.." bench-densehashmap.cpp common.c -o bench-densehashmap.exe - @./bench-densehashmap.exe 41 - @./bench-densehashmap.exe 42 - @./bench-densehashmap.exe 43 - -# COLLECTIONC shall point to the directory where it is installed -bench-collectionc: - @if test -n "$${COLLECTIONC}" ; then $(MAKE) bench-collectionc0 ; else echo "Nothing to be done for COLLECTIONC." ; fi - -bench-collectionc0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${COLLECTIONC}/include/collectc" bench-collectionc.c common.c "$${COLLECTIONC}/lib/libcollectc.a" -o bench-collectionc.exe - @./bench-collectionc.exe 10 - @./bench-collectionc.exe 20 - @./bench-collectionc.exe 30 - @./bench-collectionc.exe 40 - @./bench-collectionc.exe 41 - @./bench-collectionc.exe 50 - -# TOMMYDS shall point to the source directory. -bench-tommyds: - @if test -n "$${TOMMYDS}" ; then $(MAKE) bench-tommyds0 ; else echo "Nothing to be done for TOMMYDS." ; fi - -bench-tommyds0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${TOMMYDS}" bench-tommyds.c $${TOMMYDS}/tommyds/tommyarray.c $${TOMMYDS}/tommyds/tommylist.c $${TOMMYDS}/tommyds/tommytree.c $${TOMMYDS}/tommyds/tommyhashlin.c common.c -o bench-tommyds.exe - @./bench-tommyds.exe 10 - @./bench-tommyds.exe 20 - @./bench-tommyds.exe 30 - @./bench-tommyds.exe 40 - @./bench-tommyds.exe 41 - -# FLATHASHMAP shall point to the directory where the headers are -bench-flathashmap: - @if test -n "$${FLATHASHMAP}" ; then $(MAKE) bench-flathashmap0 ; else echo "Nothing to be done for FLATHASHMAP." ; fi - -bench-flathashmap0: - $(CXX) -std=c++14 $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${FLATHASHMAP}" bench-flathashmap.cpp common.c -o bench-flathashmap.exe - @./bench-flathashmap.exe 41 - @./bench-flathashmap.exe 42 - @./bench-flathashmap.exe 46 - @./bench-flathashmap.exe 43 - -# EMILIB shall point to the directory where the headers are -bench-emilib: - @if test -n "$${EMILIB}" ; then $(MAKE) bench-emilib0 ; else echo "Nothing to be done for EMILIB." ; fi - -bench-emilib0: - $(CXX) -std=c++14 $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${EMILIB}" bench-emilib.cpp common.c -o bench-emilib.exe - @./bench-emilib.exe 41 - @./bench-emilib.exe 42 - @./bench-emilib.exe 46 - @./bench-emilib.exe 43 - -# EMHASh shall point to the directory where the headers are -bench-emhash: - @if test -n "$${EMHASH}" ; then $(MAKE) bench-emhash0 ; else echo "Nothing to be done for EMHASH." ; fi - -bench-emhash0: - $(CXX) -std=c++14 $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${EMHASH}" bench-emhash.cpp common.c -o bench-emhash.exe - @./bench-emhash.exe 41 - @./bench-emhash.exe 42 - @./bench-emhash.exe 46 - @./bench-emhash.exe 43 - -# HOPSCOTCHMAP shall point to the directory where the source are -bench-hopscotchmap: - @if test -n "$${HOPSCOTCHMAP}" ; then $(MAKE) bench-hopscotchmap0 ; else echo "Nothing to be done for HOPSCOTCHMAP." ; fi - -bench-hopscotchmap0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${HOPSCOTCHMAP}/include/tsl" bench-hopscotchmap.cpp common.c -o bench-hopscotchmap.exe - @./bench-hopscotchmap.exe 41 - @./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 for UTHASH." ; fi - -bench-uthash0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${UTHASH}" bench-uthash.c common.c -o bench-uthash.exe - @./bench-uthash.exe 10 - @./bench-uthash.exe 20 - @./bench-uthash.exe 40 - @./bench-uthash.exe 41 - @./bench-uthash.exe 50 - -# QLIBC shall point to the directory where the library is installed. -bench-qlibc: - @if test -n "$${QLIBC}" ; then $(MAKE) bench-qlibc0 ; else echo "Nothing to be done for QLIBC." ; fi - -bench-qlibc0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${QLIBC}/include" -L "$${QLIBC}/lib" -lqlibc -pthread bench-qlibc.c common.c -o bench-qlibc.exe - @LD_LIBRARY_PATH="$${QLIBC}/lib:$${LD_LIBRARY_PATH}" ./bench-qlibc.exe 10 - @LD_LIBRARY_PATH="$${QLIBC}/lib:$${LD_LIBRARY_PATH}" ./bench-qlibc.exe 20 - @LD_LIBRARY_PATH="$${QLIBC}/lib:$${LD_LIBRARY_PATH}" ./bench-qlibc.exe 30 - -# LIBSRT shall point to the directory where it is installed -bench-libsrt: - @if test -n "$${LIBSRT}" ; then $(MAKE) bench-libsrt0 ; else echo "Nothing to be done for LIBSRT." ; fi - -bench-libsrt0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${LIBSRT}/src" bench-libsrt.c common.c -o bench-libsrt.exe $${LIBSRT}/src/.libs/libsrt.a - @./bench-libsrt.exe 20 - @./bench-libsrt.exe 50 - - -# LIBLFDS shall point to the directory where the bin/build/inc/obj/src directories are -# 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) $(XCFLAGS) $(CPPFLAGS) -I "$${LIBLFDS}/inc" -Wno-unknown-pragmas bench-liblfds.c common.c -DMULTI_THREAD_MEASURE -o bench-liblfds.exe $${LIBLFDS}/bin/liblfds711.a -lpthread - @LD_LIBRARY_PATH="$${LIBLFDS}/bin:$${LD_LIBRARY_PATH}" ./bench-liblfds.exe 60 - - -# CONCURRENTQUEUE shall point to the directory where the bin/build/inc/obj/src directories are -# 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) $(XCFLAGS) $(CPPFLAGS) -I "$${CONCURRENTQUEUE}/" bench-concurrentqueue.cpp common.c -DMULTI_THREAD_MEASURE -o bench-concurrentqueue.exe -lpthread - @./bench-concurrentqueue.exe 60 - - -# XXHASH shall point to the source directory of xxhash -# The library shall be built. -bench-xxhash: - @if test -n "$${XXHASH}" ; then $(MAKE) bench-xxhash0 ; else echo "Nothing to be done for XXHASH." ; fi -bench-xxhash0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${XXHASH}/" bench-xxhash.c common.c "$${XXHASH}/libxxhash.a" -o bench-xxhash.exe - @./bench-xxhash.exe 70 - -# BOOST shall point to the header location. -bench-boost: - @if test -n "$${BOOST}" ; then $(MAKE) bench-boost0 ; else echo "Nothing to be done for BOOST." ; fi -bench-boost0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${BOOST}" bench-boost.cpp common.c -DMULTI_THREAD_MEASURE -o bench-boost-thread.exe -lpthread - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${BOOST}" bench-boost.cpp common.c -o bench-boost.exe -lpthread - @./bench-boost.exe 42 - @./bench-boost.exe 41 - @./bench-boost-thread.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) $(XCFLAGS) $(CPPFLAGS) -I "$${NEDTRIES}" bench-nedtries.c common.c -o bench-nedtries.exe - @./bench-nedtries.exe 40 - @./bench-nedtries.exe 45 - -# RIGTORP_HASHMAP shall point to the directory where the headers are -bench-rigtorp-hashmap: - @if test -n "$${RIGTORP_HASHMAP}" ; then $(MAKE) bench-rigtorp-hashmap0 ; else echo "Nothing to be done for RIGTORP_HASHMAP." ; fi - -bench-rigtorp-hashmap0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${RIGTORP_HASHMAP}/include" bench-rigtorp-hashmap.cpp common.c -o bench-rigtorp-hashmap.exe - @./bench-rigtorp-hashmap.exe 42 - @./bench-rigtorp-hashmap.exe 41 - @./bench-rigtorp-hashmap.exe 43 - -# RIGTORP_MPMC_QUEUE shall point to the directory where the headers are -bench-rigtorp-mpmc-queue: - @if test -n "$${RIGTORP_MPMC_QUEUE}" ; then $(MAKE) bench-rigtorp-mpmc-queue0 ; else echo "Nothing to be done for RIGTORP_MPMC_QUEUE." ; fi -bench-rigtorp-mpmc-queue0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${RIGTORP_MPMC_QUEUE}" bench-rigtorp-mpmcqueue.cpp common.c -DMULTI_THREAD_MEASURE -o bench-mpmcqueue.exe -lpthread - @./bench-mpmcqueue.exe 60 - -# CTL shall point to the source directory (not where the headers are) -bench-ctl: - @if test -n "$${CTL}" ; then $(MAKE) bench-ctl0 ; else echo "Nothing to be done for CTL." ; fi - -bench-ctl0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${CTL} bench-ctl.c common.c -o bench-ctl.exe - @./bench-ctl.exe 10 - @./bench-ctl.exe 20 - @./bench-ctl.exe 30 - @./bench-ctl.exe 40 - @./bench-ctl.exe 50 - -# STC shall point to the source directory (not where the headers are) -bench-stc: - @if test -n "$${STC}" ; then $(MAKE) bench-stc0 ; else echo "Nothing to be done for STC." ; fi - -bench-stc0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${STC}/include bench-stc.c common.c -o bench-stc.exe - @./bench-stc.exe 10 - @./bench-stc.exe 20 - @./bench-stc.exe 30 - @./bench-stc.exe 40 - @./bench-stc.exe 41 - @./bench-stc.exe 50 - -# POTTERY shall point to the source directory (not where the headers are) -bench-pottery: - @if test -n "$${POTTERY}" ; then $(MAKE) bench-pottery0 ; else echo "Nothing to be done for POTTERY." ; fi - -bench-pottery0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -DPOTTERY_AVAILABLE=1 -I $${POTTERY}/include bench-pottery.c common.c -o bench-pottery.exe - @./bench-pottery.exe 10 - @./bench-pottery.exe 20 - @./bench-pottery.exe 30 - @./bench-pottery.exe 40 - @./bench-pottery.exe 41 - @./bench-pottery.exe 50 - -# CCLIB shall point to the source directory of CC (where the headers are) -bench-CC: - @if test -n "$${CCLIB}" ; then $(MAKE) bench-CC0 ; else echo "Nothing to be done for CC." ; fi - -bench-CC0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${CCLIB}/ bench-CC.c common.c -o bench-CC.exe - @./bench-CC.exe 10 - @./bench-CC.exe 20 - @./bench-CC.exe 40 - @./bench-CC.exe 41 - -# VERSTABLE shall point to the source directory of VERSTABLE (where the headers are) -bench-verstable: - @if test -n "$${VERSTABLE}" ; then $(MAKE) bench-verstable0 ; else echo "Nothing to be done for VERSTABLE." ; fi - -bench-verstable0: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I $${VERSTABLE}/ bench-verstable.c common.c -o bench-verstable.exe - @./bench-verstable.exe 40 - @./bench-verstable.exe 41 - -############################################################################ - -bench-mlib-json: bench-mlib - @./bench-mlib.exe 110 - @./bench-mlib.exe 111 - @./bench-mlib.exe 112 - -bench-rapidjson: - @if test -n "$${RAPIDJSON}" ; then $(MAKE) bench-rapidjson0 ; else echo "Nothing to be done for RAPIDJSON." ; fi -bench-rapidjson0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -I "$${RAPIDJSON}/" bench-rapidjson.cpp common.c -o bench-rapidjson.exe - @./bench-rapidjson.exe 110 - @./bench-rapidjson.exe 111 - @./bench-rapidjson.exe 112 - -############################################################################ - -bench-plain: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) bench-plain-c.c -o bench-plain-c.exe - @./bench-plain-c.exe - -############################################################################ - -bench-mempool: - @if test -n "$${BOOST}" ; then if test -n "$${GLIB}" ; then make bench-mempool0 BENCH_DEF="-DUSE_BOOST -DUSE_GLIB `pkg-config --libs --cflags glib-2.0` -lboost_system" ; else make bench-mempool0 BENCH_DEF="-DUSE_BOOST -lboost_system" ; fi ; else if test -n "$${GLIB}" ; then make bench-mempool0 BENCH_DEF="-DUSE_GLIB `pkg-config --libs --cflags glib-2.0`" ; else make bench-mempool0 ; fi ; fi -bench-mempool0: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) pool.cc $(BENCH_DEF) -o bench-mempool.exe - @./bench-mempool.exe - -############################################################################ - -bench-maxdict: - $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) max-dict.c -o bench-max-dict.exe - @./bench-max-dict.exe - -############################################################################ - -# BSTRLIB shall point to the BSTRLIB sources -# LIBSRT shall point to the LIBSRT sources -bench-string: - @if test -n "$${BSTRLIB}" ; then $(MAKE) bench-string-step1 BENCH_DEF="-DBENCH_CAN_USE_BSTRLIB -I ${BSTRLIB} $${BSTRLIB}/obj/bstrlib.o $${BSTRLIB}/obj/bstraux.o $${BSTRLIB}/obj/bstrwrap.o" ; else $(MAKE) bench-string-step1 ; fi - -bench-string-step1: - @if test -n "$${LIBSRT}" ; then $(MAKE) bench-string-step2 BENCH_DEF="$(BENCH_DEF) -DBENCH_CAN_USE_LIBSRT -I$${LIBSRT}/src $${LIBSRT}/src/.libs/libsrt.a" ; else $(MAKE) bench-string-step2 BENCH_DEF="$(BENCH_DEF)"; fi - -#NOTE: Need to build by hand sds.o since it is not build by default and sds.c is not compatible with C++ -bench-string-step2: - @if test -n "$${SDS}" ; then $(MAKE) bench-string-step4 BENCH_DEF="$(BENCH_DEF) -fpermissive -DBENCH_CAN_USE_SDS -I$${SDS}/ $${SDS}/sds.o" ; else $(MAKE) bench-string-step4 BENCH_DEF="$(BENCH_DEF)"; fi - -bench-string-step4: - @if test -n "$${GLIB}" ; then $(MAKE) bench-string-step5 BENCH_DEF="$(BENCH_DEF) -DBENCH_CAN_USE_GLIB $$(pkg-config --cflags --libs glib-2.0)" ; else $(MAKE) bench-string-step5 BENCH_DEF="$(BENCH_DEF)"; fi - -bench-string-step5: - @if test -n "$${POTTERY}" ; then $(MAKE) bench-string-step6 BENCH_DEF="$(BENCH_DEF) -DBENCH_CAN_USE_POTTERY -I$${POTTERY}/include -I$${POTTERY}/util/ $${POTTERY}/util/pottery/string/string.c" ; else $(MAKE) bench-string-step6 BENCH_DEF="$(BENCH_DEF)"; fi - -bench-string-step6: - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -DBENCH_CAN_USE_STL -DBENCH_CAN_USE_MSTARLIB bench-string.cpp common.c $(BENCH_DEF) -o bench-string.exe - $(CXX) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -DBENCH_CAN_USE_STL -DBENCH_CAN_USE_MSTARLIB bench-string-2.cpp common.c $(BENCH_DEF) -o bench-string-2.exe - @./bench-string.exe - @./bench-string-2.exe 2000000 0 - @./bench-string-2.exe 2000000 1 - @./bench-string-2.exe 2000000 2 - @./bench-string-2.exe 2000000 4 - @./bench-string-2.exe 2000000 5 - -bench-string-pgo: - $(MAKE) bench-string XCFLAGS="-fprofile-generate=pgo" - $(MAKE) bench-string XCFLAGS="-fprofile-use=pgo" - -############################################################################ - -bench-find-sort: - g++ bench-find-sort.cpp -O2 -march=native -std=c++11 -I.. -g common.c -o bench-find-sort.exe - ./bench-find-sort.exe 10000000 - -############################################################################ - -clean: - $(RM) *.o bench-*.exe - $(RM) bench-*.s *~ massif.out.* - $(RM) plot-*.dat - $(RM) pgo - $(RM) tmp-serial.* - cd nucleotide && $(MAKE) clean - -############################################################################ - -massif-do: all - @valgrind --tool=massif ./bench-mlib.exe $(N) - @valgrind --tool=massif ./bench-mlib-mempool.exe $(N) - @valgrind --tool=massif ./bench-stl.exe $(N) - @valgrind --tool=massif ./bench-qt.exe $(N) - @valgrind --tool=massif ./bench-glib.exe $(N) - @test -f ./bench-klib.exe && valgrind --tool=massif ./bench-klib.exe $(N) - @test -f ./bench-libdynamic.exe && valgrind --tool=massif ./bench-libdynamic.exe $(N) - -massif-visu: - test -f massif.out.* || $(MAKE) massif-do - for i in massif.out.* ; do ms_print $$i|head -30 ; done diff --git a/bench/bench-CC.c b/bench/bench-CC.c deleted file mode 100644 index 8e989e1a..00000000 --- a/bench/bench-CC.c +++ /dev/null @@ -1,140 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "common.h" - -#include "cc.h" - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - vec( unsigned int ) a1, a2; - init(&a1); - init(&a2); - - for(size_t i = 0; i < n; i++) { - push(&a1, rand_get() ); - push(&a2, rand_get() ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += *get(&a1, i ) * *get(&a2, i ); - } - g_result = s; - - cleanup(&a1); - cleanup(&a2); -} - -/********************************************************************************************/ - -static void test_list(size_t n) -{ - list( unsigned int ) a1, a2; - init(&a1); - init(&a2); - - for(size_t i = 0; i < n; i++) { - push(&a1, rand_get() ); - push(&a2, rand_get() ); - } - unsigned int s = 0; - for(unsigned *it1 = first( &a1 ), *it2 = first( &a2 ); it1 != end( &a1 ); it1 = next( &a1, it1 ), it2 = next(&a2, it2) ) { - s += *it1 * *it2; - } - g_result = s; - - cleanup(&a1); - cleanup(&a2); -} - -/********************************************************************************************/ - -static void -test_dict(size_t n) -{ - map( unsigned long, unsigned long ) dict; - init(&dict); - - for (size_t i = 0; i < n; i++) { - unsigned long value = rand_get(); - unsigned long key = rand_get(); - insert(&dict, key, value); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long key = rand_get(); - const unsigned long *val = get(&dict, key); - if (val != NULL) - s += *val; - } - g_result = s; - - cleanup(&dict); -} - -/********************************************************************************************/ -typedef struct { - char a[256]; -} char_array_t; -static inline void char_init (char_array_t *a) { a->a[0] = 0; } -static inline void char_set (char_array_t *a, const char_array_t b) { strcpy(a->a, b.a); } -static inline bool char_equal_p (const char_array_t *a, const char_array_t *b) { return strcmp(a->a,b->a)==0; } -static inline bool char_cmp (const char_array_t *a, const char_array_t *b) { return strcmp(a->a,b->a); } -static inline void char_clear (char_array_t *a) { (void)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; -} -#define CC_DTOR char_array_t, { char_clear(&val); } -#define CC_CMPR char_array_t, { return char_cmp(&val_1, &val_2); } -#define CC_HASH char_array_t, { return char_hash(&val); } -#include "cc.h" - -static void -test_dict_big(size_t n) -{ - map( char_array_t, char_array_t) dict; - init(&dict); - - 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()); - 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()); - const char_array_t *val = get(&dict, s1); - if (val != NULL) - s ++; - } - g_result = s; - - cleanup(&dict); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 20, "Array", 100000000, 0, test_array, 0}, - { 40, "dict", 1000000, 0, test_dict, 0}, - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("CC", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-boost.cpp b/bench/bench-boost.cpp deleted file mode 100644 index 39fe7a21..00000000 --- a/bench/bench-boost.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include "m-thread.h" - -#include -#include - -#include "common.h" - -using namespace std; - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - boost::unordered_flat_map dict; - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - boost::unordered_flat_map::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -static void -test_dict2_linear(size_t n) -{ - boost::unordered_flat_map dict; - for (size_t i = 0; i < n; i++) { - dict[i] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - boost::unordered_flat_map::iterator it = dict.find(i); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -inline std::size_t hash_value(const char_array_s &k) { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; -} - -static void -test_dict_big(size_t n) -{ - boost::unordered_flat_map dict; - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - boost::unordered_flat_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -static void -test_dict_str(size_t n) -{ - boost::unordered_flat_map dict; - - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - string s2 = static_cast( &(ostringstream() << rand_get()) )->str(); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - boost::unordered_flat_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -boost::lockfree::queue> g_buff; -boost::lockfree::queue> g_final; - -static void final(void *arg) -{ - size_t *p_n = (size_t*) arg; - size_t n = *p_n; - unsigned long long j, s = 0; - for(unsigned int i = 0; i < n;i++) { - while (!g_final.pop(j)); - s += j; - } - g_result = s; -} - -static void conso(void *arg) -{ - unsigned int j; - size_t *p_n = (size_t*)arg; - size_t n = *p_n; - unsigned long long s = 0; - for(unsigned int i = 0; i < n;i++) { - while (!g_buff.pop(j)); - s += j; - } - while (!g_final.push(s)); -} - -static void prod(void *arg) -{ - size_t *p_n = (size_t*)arg; - size_t n = *p_n; - size_t r = n; - for(unsigned int i = 0; i < n;i++) { - while (!g_buff.push(r)); - r = r * 31421U + 6927U; - } -} - -static void test_queue(size_t n) -{ - const int cpu_count = get_cpu_count(); - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - if (cpu_count < 2) { - fprintf(stderr, "WARNING: Can not measure Buffer performance.\n"); - return; - } - rand_get(); - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - -} - - -/********************************************************************************************/ - -const config_func_t table[] = { - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42, "dict", 1000000, 0, test_dict2, 0}, - { 43, "DictStr", 1000000, 0, test_dict_str, 0}, - { 46, "DictLinear", 1000000, 0, test_dict2_linear, 0}, - { 60, "Queue MPMC", 1000000, 0, test_queue, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("BOOST", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-cmc.c b/bench/bench-cmc.c deleted file mode 100644 index 1fb8a709..00000000 --- a/bench/bench-cmc.c +++ /dev/null @@ -1,204 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "macro_collections.h" - -#include "common.h" - -/********************************************************************************************/ - -// CMC list are dynamic array -#define MY_LIST_PARAMS (list_uint, list_uint_s, , , unsigned int) -C_MACRO_COLLECTIONS_EXTENDED(CMC, LIST, MY_LIST_PARAMS, (STR)) - -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) ) - -#define MY_TMAP_PARAMS (tree_ulong, tree_ulong_s, , unsigned long, bool) -C_MACRO_COLLECTIONS_EXTENDED(CMC, TREEMAP, MY_TMAP_PARAMS, (STR)) - -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); -} - -#define MY_DICT_PARAMS (hmap, hmap_s, , unsigned long, unsigned long) -C_MACRO_COLLECTIONS_EXTENDED(CMC, HASHMAP, MY_DICT_PARAMS, (STR)) - -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; -} - -#define MY_DICTB_PARAMS (bhmap, bhmap_s, , char_array_t, char_array_t) -C_MACRO_COLLECTIONS_EXTENDED(CMC, HASHMAP, MY_DICT_PARAMS, (STR)) - -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 - -/********************************************************************************************/ - -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); -} - diff --git a/bench/bench-collectionc.c b/bench/bench-collectionc.c deleted file mode 100644 index 72be13e7..00000000 --- a/bench/bench-collectionc.c +++ /dev/null @@ -1,266 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "array.h" -#include "slist.h" -#include "treetable.h" -#include "hashtable.h" - -#include "common.h" - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - Array *a1, *a2; - enum cc_stat stat; - - stat = array_new(&a1); - if (stat != CC_OK) abort(); - stat = array_new(&a2); - if (stat != CC_OK) abort(); - - for(size_t i = 0; i < n; i++) { - stat = array_add(a1, (void*) (uintptr_t)rand_get() ); - if (stat != CC_OK) abort(); - stat = array_add(a2, (void*) (uintptr_t)rand_get() ); - if (stat != CC_OK) abort(); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - void *e, *f; - stat = array_get_at(a1, i, &e); - if (stat != CC_OK) abort(); - stat = array_get_at(a2, i, &f); - if (stat != CC_OK) abort(); - s += ((unsigned int)(uintptr_t) e) * ((unsigned int)(uintptr_t) f); - } - g_result = s; - - array_destroy(a1); - array_destroy(a2); -} - -/********************************************************************************************/ - -static void test_list(size_t n) -{ - SList *a1, *a2; - enum cc_stat stat; - - stat = slist_new(&a1); - if (stat != CC_OK) abort(); - stat = slist_new(&a2); - if (stat != CC_OK) abort(); - - for(size_t i = 0; i < n; i++) { - stat = slist_add(a1, (void*) (uintptr_t)rand_get() ); - if (stat != CC_OK) abort(); - stat = slist_add(a2, (void*) (uintptr_t)rand_get() ); - if (stat != CC_OK) abort(); - } - unsigned int s = 0; - SListIter iter1, iter2; - void *e, *f; - slist_iter_init(&iter1, a1); - slist_iter_init(&iter2, a2); - while (slist_iter_next(&iter1, &e) == CC_OK && slist_iter_next(&iter2, &f) == CC_OK) { - s += ((unsigned int)(uintptr_t) e) * ((unsigned int)(uintptr_t) f); - } - g_result = s; - - slist_destroy(a1); - slist_destroy(a2); -} - -/********************************************************************************************/ - -static int compare(const void *a, const void *b) -{ - const uintptr_t pa = (uintptr_t) a; - const uintptr_t pb = (uintptr_t) b; - return (pa < pb) ? -1 : (pa > pb); -} - -static void test_rbtree(size_t n) -{ - TreeTable *tree; - enum cc_stat stat; - - stat = treetable_new(compare, &tree); - if (stat != CC_OK) abort(); - for (size_t i = 0; i < n; i++) { - void *key = (void*)(uintptr_t) rand_get(); - stat = treetable_add(tree, key, key); - if (stat != CC_OK) abort(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - void *e; - void *key = (void*) (uintptr_t) rand_get(); - stat = treetable_get(tree, key, &e); - if (stat == CC_OK) - s += (uintptr_t)e; - } - g_result = s; - treetable_destroy(tree); -} - -/********************************************************************************************/ -static size_t hash_func (const void *key, int l, uint32_t seed) -{ - const unsigned long pa = (uintptr_t) key; - (void)l; - return pa ^ seed; -} - -static int equal_func(const void *key1, const void *key2) -{ - const unsigned long pa = (uintptr_t) key1; - const unsigned long pb = (uintptr_t) key2; - return (pa < pb) ? -1 : pa > pb; -} - -static void -test_dict(size_t n) -{ - HashTable *dict; - enum cc_stat stat; - HashTableConf htc; - hashtable_conf_init(&htc); - htc.hash = hash_func; - htc.key_compare = equal_func; - stat = hashtable_new_conf(&htc, &dict); - if (stat != CC_OK) abort(); - - for (size_t i = 0; i < n; i++) { - void *value = (void*)(uintptr_t) rand_get(); - void *key = (void*)(uintptr_t) rand_get(); - stat = hashtable_add(dict, key, value ); - if (stat != CC_OK) abort(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - void *key = (void*)(uintptr_t) rand_get(); - void *r; - stat = hashtable_get(dict, key, &r); - if (stat == CC_OK) - s += (uintptr_t) r; - } - g_result = s; - hashtable_destroy(dict); -} - -/********************************************************************************************/ - -typedef char char_array_t[256]; - -static int char_equal (const void* a, const void * b) -{ - const char_array_t *pa = (const char_array_t *)a; - const char_array_t *pb = (const char_array_t *)b; - return strcmp(*pa,*pb); -} - -static size_t char_hash(const void *a, int l, uint32_t seed) -{ - const char_array_t *pa = (const char_array_t *)a; - const char *s = *pa; - (void)l ; - size_t hash = seed; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; -} - -static void -test_dict_big(size_t n) -{ - HashTable *dict; - enum cc_stat stat; - HashTableConf htc; - hashtable_conf_init(&htc); - htc.hash = char_hash; - htc.key_compare = char_equal; - stat = hashtable_new_conf(&htc, &dict); - if (stat != CC_OK) abort(); - - char_array_t **tab = malloc (sizeof(char_array_t *)*2*n); - if (!tab) abort(); - size_t cpt = 0; - for (size_t i = 0; i < n; i++) { - char_array_t *key = malloc (sizeof (char_array_t)); - char_array_t *value = malloc (sizeof (char_array_t)); - tab[cpt++] = key; - tab[cpt++] = value; - sprintf(*key, "%u", rand_get()); - sprintf(*value, "%u", rand_get()); - stat = hashtable_add(dict, key, value ); - if (stat != CC_OK) abort(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_t s1; - void *r; - sprintf(s1, "%u", rand_get()); - stat = hashtable_get(dict, s1, &r); - if (stat == CC_OK) - s ++; - } - g_result = s; - hashtable_destroy(dict); - if (cpt != 2*n) abort(); - for(size_t i = 0; i < 2*n;i++) - free(tab[i]); -} - -/********************************************************************************************/ - -static int cmp_float(const void * a, const void *b) -{ - const float *const*pa = a, *const*pb = b; - return (**pa < **pb) ? -1 : (**pa > **pb); -} - -static void test_sort(size_t n) -{ - Array *a1; - enum cc_stat stat; - - stat = array_new(&a1); - if (stat != CC_OK) abort(); - for(size_t i = 0; i < n; i++) { - float *v = malloc(sizeof(float)); - *v = rand_get(); - stat = array_add(a1, v ); - if (stat != CC_OK) abort(); - } - array_sort(a1, cmp_float); - void *e; - stat = array_get_at(a1, 0, &e); - if (stat != CC_OK) abort(); - g_result = *(float*)e; - array_destroy(a1); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 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}, - { 50, "Sort",10000000, 0, test_sort, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("CollectionC", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-concurrentqueue.cpp b/bench/bench-concurrentqueue.cpp deleted file mode 100644 index a073acd1..00000000 --- a/bench/bench-concurrentqueue.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "concurrentqueue.h" - -#include "common.h" - -/********************************************************************************************/ -moodycamel::ConcurrentQueue g_buff; -moodycamel::ConcurrentQueue g_final; - -static void final(void *arg) -{ - size_t *p_n = (size_t*) arg; - size_t n = *p_n; - unsigned long long j, s = 0; - for(unsigned int i = 0; i < n;i++) { - while (!g_final.try_dequeue(j)); - s += j; - } - g_result = s; -} - -static void conso(void *arg) -{ - unsigned int j; - size_t *p_n = (size_t*)arg; - size_t n = *p_n; - unsigned long long s = 0; - for(unsigned int i = 0; i < n;i++) { - while (!g_buff.try_dequeue(j)); - s += j; - } - while (!g_final.try_enqueue(s)); -} - -static void prod(void *arg) -{ - size_t *p_n = (size_t*)arg; - size_t n = *p_n; - size_t r = n; - for(unsigned int i = 0; i < n;i++) { - while (!g_buff.try_enqueue(r)); - r = r * 31421U + 6927U; - } -} - -static void test_queue(size_t n) -{ - const int cpu_count = get_cpu_count(); - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - if (cpu_count < 2) { - fprintf(stderr, "WARNING: Can not measure Buffer performance.\n"); - return; - } - rand_get(); - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - -} - - -/********************************************************************************************/ - -const config_func_t table[] = { - { 60, "Queue MPMC", 1000000, 0, test_queue, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("CONCURRENT-QUEUE", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-ctl.c b/bench/bench-ctl.c deleted file mode 100644 index 3a49157c..00000000 --- a/bench/bench-ctl.c +++ /dev/null @@ -1,183 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "m-core.h" -#include "common.h" - -typedef unsigned int uint; -typedef unsigned long ulong; - -/********************************************************************************************/ -#define POD -#define T uint -#include "ctl/vector.h" - -static void test_array(size_t n) -{ - vec_uint a1 = vec_uint_init(); - vec_uint a2 = vec_uint_init(); - - for(size_t i = 0; i < n; i++) { - vec_uint_push_back(&a1, rand_get() ); - vec_uint_push_back(&a2, rand_get() ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += *vec_uint_at(&a1, i ) * *vec_uint_at(&a2, i ); - } - g_result = s; - - vec_uint_free(&a1); - vec_uint_free(&a2); -} - -/********************************************************************************************/ - -#define POD -#define T uint -#include "ctl/forward_list.h" - -static void test_list (size_t n) -{ - slist_uint a1 = slist_uint_init(); - slist_uint a2 = slist_uint_init(); - - for(size_t i = 0; i < n; i++) { - slist_uint_push_front(&a1, rand_get()); - slist_uint_push_front(&a2, rand_get()); - } - unsigned int s = 0; - slist_uint_it it1 = slist_uint_begin(&a1); - slist_uint_it it2 = slist_uint_begin(&a2); - for( ; !slist_uint_it_done(&it1) ; - slist_uint_it_next(&it1), slist_uint_it_next(&it2)) { - s += *slist_uint_it_ref(&it1) * *slist_uint_it_ref(&it2); - } - g_result = s; - - slist_uint_free(&a1); - slist_uint_free(&a2); -} - -/********************************************************************************************/ - -#define POD -#define T ulong -#include "ctl/set.h" - -static inline int -int_cmp(ulong *a, ulong *b) { - return *a < *b; -} - -static void test_rbtree(size_t n) -{ - set_ulong tree = set_ulong_init (int_cmp); - - for (size_t i = 0; i < n; i++) { - set_ulong_insert (&tree, rand_get() ); - } - - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long j = rand_get(); - if (set_ulong_find_node(&tree, j) != NULL) - s+= j; - } - g_result = s; - set_ulong_free(&tree); -} - -/********************************************************************************************/ - -typedef struct { - unsigned long key; - unsigned long value; -} pair_ulong; - -// Use of M*LIB hash function -static inline size_t -pair_ulong_hash(pair_ulong *a) -{ - return M_HASH_DEFAULT(a->key); -} - -static inline int -pair_ulong_equal(pair_ulong *a, pair_ulong *b) -{ - return a->key == b->key; -} - -static inline void -pair_ulong_free(pair_ulong *a) { - (void) a; -} - -static inline pair_ulong -pair_ulong_copy(pair_ulong *self) { - return (pair_ulong) { .key = self->key, .value = self->value }; -} - -#define T pair_ulong -#include - -static void -test_dict(size_t n) -{ - umap_pair_ulong dict = umap_pair_ulong_init(pair_ulong_hash, pair_ulong_equal); - - for (size_t i = 0; i < n; i++) { - unsigned long value = rand_get(); - unsigned long key = rand_get(); - umap_pair_ulong_insert(&dict, (pair_ulong) { key, value }); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - umap_pair_ulong_it it = umap_pair_ulong_find(&dict, (pair_ulong) { rand_get() , 0 } ); - if (!umap_pair_ulong_it_done(&it) ) - s += it.ref->value; - } - g_result = s; - - umap_pair_ulong_free(&dict); -} - -/********************************************************************************************/ - -#define POD -#define T float -#include "ctl/vector.h" - -static void test_sort(size_t n) -{ - vec_float a1 = vec_float_init(); - - for(size_t i = 0; i < n; i++) { - vec_float_push_back(&a1, rand_get()); - } - vec_float_sort(&a1); - g_result = *vec_float_at(&a1, 0); - vec_float_free(&a1); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 20, "Array", 100000000, 0, test_array, 0}, - { 30, "Rbtree", 1000000, 0, test_rbtree, 0}, - { 40, "dict", 1000000, 0, test_dict, 0}, - { 50, "Sort", 10000000, 0, test_sort, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("CTL", numberof(table), table, argc, argv); - exit(0); -} - diff --git a/bench/bench-densehashmap.cpp b/bench/bench-densehashmap.cpp deleted file mode 100644 index 4408669b..00000000 --- a/bench/bench-densehashmap.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -using google::dense_hash_map; -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - dense_hash_map dict; - dict.set_empty_key(-1); - dict.set_deleted_key(-2); - - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - dense_hash_map::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ - -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -namespace std { - template <> struct hash { - std::size_t operator()(const char_array_s &k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; - namespace tr1 { - template <> struct hash { - std::size_t operator()(char_array_s k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; - } -} - -static void -test_dict_big(size_t n) -{ - dense_hash_map dict; - struct char_array_s empty, del; - memset(&empty, 0, sizeof empty); empty.a[1] = 255; - memset(&del, 0, sizeof del); del.a[1] = 255; - dict.set_empty_key(empty); - dict.set_deleted_key(del); - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - dense_hash_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -static void -test_dict_str(size_t n) -{ - dense_hash_map dict; - string empty, del; - empty = ""; - del = "DEL"; - dict.set_empty_key(empty); - dict.set_deleted_key(del); - - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - string s2 = static_cast( &(ostringstream() << rand_get()) )->str(); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - dense_hash_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict", 1000000, 0, test_dict2, 0}, - { 43, "DictStr", 1000000, 0, test_dict_str, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("DENSE-HASPMAP", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-emhash.cpp b/bench/bench-emhash.cpp deleted file mode 100644 index 3c90357b..00000000 --- a/bench/bench-emhash.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "hash_table7.hpp" - -using namespace emhash7; -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - HashMap dict; - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - HashMap::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -static void -test_dict2_linear(size_t n) -{ - HashMap dict; - for (size_t i = 0; i < n; i++) { - dict[i] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - HashMap::iterator it = dict.find(i); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -namespace std { - template <> struct hash { - std::size_t operator()(const char_array_s &k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; -} - -static void -test_dict_big(size_t n) -{ - HashMap dict; - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - HashMap::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -static void -test_dict_str(size_t n) -{ - HashMap dict; - - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - string s2 = static_cast( &(ostringstream() << rand_get()) )->str(); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - HashMap::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict", 1000000, 0, test_dict2, 0}, - { 43, "DictStr", 1000000, 0, test_dict_str, 0}, - { 46, "DictLinear", 1000000, 0, test_dict2_linear, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("EMHASH", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-emilib.cpp b/bench/bench-emilib.cpp deleted file mode 100644 index fa513614..00000000 --- a/bench/bench-emilib.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "emilib/hash_map.hpp" - -using namespace emilib; -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - HashMap dict; - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - HashMap::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -static void -test_dict2_linear(size_t n) -{ - HashMap dict; - for (size_t i = 0; i < n; i++) { - dict[i] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - HashMap::iterator it = dict.find(i); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -namespace std { - template <> struct hash { - std::size_t operator()(const char_array_s &k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; -} - -static void -test_dict_big(size_t n) -{ - HashMap dict; - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - HashMap::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -static void -test_dict_str(size_t n) -{ - HashMap dict; - - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - string s2 = static_cast( &(ostringstream() << rand_get()) )->str(); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - HashMap::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict", 1000000, 0, test_dict2, 0}, - { 43, "DictStr", 1000000, 0, test_dict_str, 0}, - { 46, "DictLinear", 1000000, 0, test_dict2_linear, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("EMILIB", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-find-sort.cpp b/bench/bench-find-sort.cpp deleted file mode 100644 index da17ec7a..00000000 --- a/bench/bench-find-sort.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// program to find longest contiguous subsequence -// based on https://www.geeksforgeeks.org/longest-consecutive-subsequence/ -#include -#include - -using namespace std; - -// Returns length of the longest contiguous subsequence -int cpp_find_longest(int arr[], int n) -{ - unordered_set S; - int ans = 0; - - // Hash all the array elements - for (int i = 0; i < n; i++) - S.insert(arr[i]); - - // check each possible sequence from - // the start then update optimal length - for (int i = 0; i < n; i++) { - // if current element is the starting - // element of a sequence - if (S.find(arr[i] - 1) == S.end()) { - // Then check for next elements - // in the sequence - int j = arr[i] + 1; - while (S.find(j) != S.end()) - j++; - - // update optimal length if - // this length is more - ans = max(ans, j - arr[i]); - } - } - return ans; -} - -#include "m-dict.h" - -static inline bool oor_equal_p(int a, unsigned char c) { return a == ((c == 0) ? INT_MIN : INT_MAX); } -static inline void oor_set(int *a, unsigned char c) { *a = ((c == 0) ? INT_MIN : INT_MAX); } - -DICT_OASET_DEF(dict_int, int, M_OPEXTEND(M_DEFAULT_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR))) - -// Returns length of the longest contiguous subsequence -int mlib_find_longest(int arr[], int n) -{ - dict_int_t S; - int ans = 0; - - dict_int_init(S); - - // Hash all the array elements - for (int i = 0; i < n; i++) - dict_int_push(S, arr[i]); - - // check each possible sequence from - // the start then update optimal length - for (int i = 0; i < n; i++) { - // if current element is the starting - // element of a sequence - int *p = dict_int_get(S, arr[i]-1); - if (p == NULL) { - // Then check for next elements - // in the sequence - int j = arr[i] + 1; - while (dict_int_get(S, j) != NULL) - j++; - - // update optimal length if - // this length is more - ans = M_MAX(ans, j - arr[i]); - } - } - - dict_int_clear(S); - return ans; -} - -#include "common.h" - -int main(int argc, const char *argv[]) -{ - int n = argc == 1 ? 10000 : atoi(argv[1]); - int *arr = (int*) malloc(n * sizeof(int)); - for(int i = 0; i < n; i++) - arr[i] = rand_get(); - - unsigned long long t0 = cputime(); - cout << "Length of the Longest contiguous subsequence is " - << cpp_find_longest(arr, n) << endl; - - unsigned long long t1 = cputime(); - - cout << "Length of the Longest contiguous subsequence is " - << mlib_find_longest(arr, n) << endl; - unsigned long long t2 = cputime(); - - cout << "Time C++: " << (t1-t0) << " Time M*LIB: " << (t2-t1) << endl; - return 0; -} diff --git a/bench/bench-flathashmap.cpp b/bench/bench-flathashmap.cpp deleted file mode 100644 index 7918ad0d..00000000 --- a/bench/bench-flathashmap.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// Need recent gcc -#define NDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "flat_hash_map.hpp" - -using namespace ska; -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - flat_hash_map dict; - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - flat_hash_map::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -static void -test_dict2_linear(size_t n) -{ - flat_hash_map dict; - for (size_t i = 0; i < n; i++) { - dict[i] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - flat_hash_map::iterator it = dict.find(i); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -namespace std { - template <> struct hash { - std::size_t operator()(const char_array_s &k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; -} - -static void -test_dict_big(size_t n) -{ - flat_hash_map dict; - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - flat_hash_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -static void -test_dict_str(size_t n) -{ - flat_hash_map dict; - - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - string s2 = static_cast( &(ostringstream() << rand_get()) )->str(); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - flat_hash_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict", 1000000, 0, test_dict2, 0}, - { 43, "DictStr", 1000000, 0, test_dict_str, 0}, - { 46, "DictLinear", 1000000, 0, test_dict2_linear, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("FLAT-HASPMAP", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-glib.c b/bench/bench-glib.c deleted file mode 100644 index 32414eb7..00000000 --- a/bench/bench-glib.c +++ /dev/null @@ -1,202 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include - -#include - -#include "common.h" - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - GArray *a1, *a2; - a1 = g_array_new (FALSE, FALSE, sizeof (unsigned int)); - a2 = g_array_new (FALSE, FALSE, sizeof (unsigned int)); - for(size_t i = 0; i < n; i++) { - unsigned int v = rand_get(); - g_array_append_val(a1, v ); - v = rand_get(); - g_array_append_val(a2, v ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += g_array_index(a1, unsigned int, i ) * g_array_index(a2, unsigned int, i ); - } - g_result = s; - g_array_free(a1, FALSE); - g_array_free(a2, FALSE); -} - -/********************************************************************************************/ - -static void test_list (size_t n) -{ - GSList *a1 = NULL, *a2 = NULL; - - for(size_t i = 0; i < n; i++) { - a1 = g_slist_prepend (a1, GINT_TO_POINTER (rand_get() )); - a2 = g_slist_prepend (a2, GINT_TO_POINTER (rand_get() )); - } - unsigned int s = 0; - for(GSList *it1 = a1, *it2 = a2 ; it1 != NULL; it1 = g_slist_next(it1), it2 = g_slist_next(it2) ) { - s += GPOINTER_TO_INT(it1->data) * GPOINTER_TO_INT(it2->data); - n--; - } - g_result = s; - g_slist_free(a1); - g_slist_free(a2); -} - -/********************************************************************************************/ - -static int compare(gconstpointer a, gconstpointer b, gpointer user_data) -{ - const unsigned long *pa = a; - const unsigned long *pb = b; - (void) user_data; - return (*pa < *pb) ? -1 : (*pa > *pb); -} - -static void test_rbtree(size_t n) -{ - GTree *tree = g_tree_new_full(compare, NULL, free, NULL); - for (size_t i = 0; i < n; i++) { - // NOTE: unsigned long are not designed to work with GPOINTER_TO_INT according to documentation. - unsigned long *p = malloc(sizeof(unsigned long)); - *p = rand_get(); - g_tree_insert(tree, p, p); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long key = rand_get(); - unsigned long *p = g_tree_lookup(tree, &key); - if (p) - s += *p; - } - g_result = s; - g_tree_destroy(tree); -} - -/********************************************************************************************/ -static guint hash_func (gconstpointer a) -{ - const unsigned long *pa = a; - return *pa; -} - -static gboolean equal_func(gconstpointer a, gconstpointer b) -{ - const unsigned long *pa = a; - const unsigned long *pb = b; - return *pa == *pb; -} - -static void -test_dict(size_t n) -{ - GHashTable *dict = g_hash_table_new_full(hash_func, equal_func, free, free); - for (size_t i = 0; i < n; i++) { - unsigned long *key = malloc(sizeof(unsigned long)); - unsigned long *value = malloc(sizeof(unsigned long)); - *key = rand_get(); - *value = rand_get(); - g_hash_table_insert(dict, key, value ); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long key = rand_get(); - unsigned long *p = g_hash_table_lookup(dict, &key); - if (p) - s += *p; - } - g_result = s; - g_hash_table_destroy(dict); -} - -/********************************************************************************************/ - -typedef char char_array_t[256]; - -static gboolean char_equal (gconstpointer a, gconstpointer b) -{ - const char_array_t *pa = (const char_array_t *)a; - const char_array_t *pb = (const char_array_t *)b; - return strcmp(*pa,*pb)==0; -} - -static guint char_hash(gconstpointer a) -{ - const char_array_t *pa = (const char_array_t *)a; - const char *s = *pa; - guint hash = 0; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; -} - -static void -test_dict_big(size_t n) -{ - GHashTable *dict = g_hash_table_new_full(char_hash, char_equal, free, free); - for (size_t i = 0; i < n; i++) { - char_array_t *key = malloc (sizeof (char_array_t)); - char_array_t *value = malloc (sizeof (char_array_t)); - sprintf(*key, "%u", rand_get()); - sprintf(*value, "%u", rand_get()); - g_hash_table_insert(dict, key, value ); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_t s1; - sprintf(s1, "%u", rand_get()); - char_array_t *p = g_hash_table_lookup(dict, &s1); - if (p) - s ++; - } - g_result = s; - g_hash_table_destroy(dict); -} - -/********************************************************************************************/ - -static gint cmp_float(gconstpointer a, - gconstpointer b) -{ - const float *pa = a, *pb = b; - return (*pa < *pb) ? -1 : (*pa > *pb); -} - -static void test_sort(size_t n) -{ - GArray *a1 = g_array_new (FALSE, FALSE, sizeof (float)); - for(size_t i = 0; i < n; i++) { - float v = rand_get(); - g_array_append_val(a1, v ); - } - g_array_sort(a1, cmp_float); - g_result = g_array_index (a1, float, 0); - g_array_free(a1, FALSE); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 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}, - { 50, "Sort",10000000, 0, test_sort, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("GLIB", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-hopscotchmap.cpp b/bench/bench-hopscotchmap.cpp deleted file mode 100644 index eb6b0dae..00000000 --- a/bench/bench-hopscotchmap.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "hopscotch_map.h" - -using namespace tsl; -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - tsl::hopscotch_map dict; - - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - hopscotch_map::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ - -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -namespace std { - template <> struct hash { - std::size_t operator()(const char_array_s &k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; -} - -static void -test_dict_big(size_t n) -{ - hopscotch_map dict; - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - hopscotch_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -static void -test_dict_str(size_t n) -{ - hopscotch_map dict; - - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - string s2 = static_cast( &(ostringstream() << rand_get()) )->str(); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - hopscotch_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict", 1000000, 0, test_dict2, 0}, - { 43, "DictStr", 1000000, 0, test_dict_str, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("HOPSCOTCHMAP", numberof(table), table, argc, argv); - exit(0); - -} diff --git a/bench/bench-klib.c b/bench/bench-klib.c deleted file mode 100644 index 13a90dcd..00000000 --- a/bench/bench-klib.c +++ /dev/null @@ -1,202 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "kvec.h" -#include "klist.h" -#include "kbtree.h" -#include "khash.h" -#include "ksort.h" - -#include "common.h" - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - kvec_t(unsigned int) a1, a2; - - kv_init(a1); - kv_init(a2); - - for(size_t i = 0; i < n; i++) { - kv_push(unsigned int, a1, rand_get() ); - kv_push(unsigned int, a2, rand_get() ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += kv_A(a1, i ) * kv_A(a2, i ); - } - g_result = s; - - kv_destroy(a1); - kv_destroy(a2); -} - -/********************************************************************************************/ - -#define uint_free(x) -KLIST_INIT(list_uint, unsigned int, uint_free) - -static void test_list (size_t n) -{ - klist_t(list_uint) *a1, *a2; - a1 = kl_init(list_uint); - a2 = kl_init(list_uint); - - for(size_t i = 0; i < n; i++) { - *kl_pushp (list_uint, a1) = rand_get(); - *kl_pushp (list_uint, a2) = rand_get(); - } - unsigned int s = 0; - kliter_t(list_uint) *it1, *it2; - for(it1 = kl_begin(a1), it2 = kl_begin(a2); - it1 != kl_end(a1); - it1 = kl_next(it1), it2 = kl_next(it2)) { - s += kl_val(it1) * kl_val(it2); - } - g_result = s; - - kl_destroy(list_uint, a1); - kl_destroy(list_uint, a2); -} - -/********************************************************************************************/ - -#define my_cmp(a,b) ( (a) < (b) ? -1 : (a) > (b) ) - -KBTREE_INIT(kTree, unsigned long, my_cmp) - -static void test_rbtree(size_t n) -{ - kbtree_t(kTree) *tree; - tree = kb_init(kTree, KB_DEFAULT_SIZE/2); - - for (size_t i = 0; i < n; i++) { - unsigned long j = rand_get(); - kb_putp(kTree, tree, &j); - } - - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long j = rand_get(); - if (kb_getp(kTree, tree, &j) != 0) - s+= j; - } - g_result = s; - kb_destroy(kTree, tree); -} - -/********************************************************************************************/ - -#define hash_eq(a, b) ((a) == (b)) -#define hash_func(a) kh_int64_hash_func(a) - -KHASH_INIT(iun, unsigned long, unsigned long, 1, hash_func, hash_eq) - -static void -test_dict(size_t n) -{ - khash_t(iun) *dict = kh_init(iun); - - for (size_t i = 0; i < n; i++) { - int ret; - khiter_t k = kh_put(iun, dict, rand_get(), &ret); - kh_value(dict, k) = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - khiter_t k = kh_get(iun, dict, rand_get()); - if (kh_exist(dict, k)) - s += kh_value(dict, k); - } - g_result = s; - - kh_destroy(iun, dict); -} - -/********************************************************************************************/ - -typedef struct { - char a[256]; -} char_array_t; -static inline void char_init (char_array_t *a) { a->a[0] = 0; } -static inline void char_set (char_array_t *a, const char_array_t b) { strcpy(a->a, b.a); } -static inline bool char_equal_p (const char_array_t a, const char_array_t b) { return strcmp(a.a,b.a)==0; } -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; -} - -KHASH_INIT(iub, char_array_t, char_array_t, 1, char_hash, char_equal_p) - -static void -test_dict_big(size_t n) -{ - khash_t(iub) *dict = kh_init(iub); - - for (size_t i = 0; i < n; i++) { - int ret; - char_array_t s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - khiter_t k = kh_put(iub, dict, s1, &ret); - char_set(&kh_value(dict, k), 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()); - khiter_t k = kh_get(iub, dict, s1); - if (kh_exist(dict, k)) - s ++; - } - g_result = s; - - kh_destroy(iub, dict); -} - -/********************************************************************************************/ -// 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); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 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}, - { 50, "Sort",10000000, 0, test_sort, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("KLIB", numberof(table), table, argc, argv); - exit(0); -} - diff --git a/bench/bench-libdynamic.c b/bench/bench-libdynamic.c deleted file mode 100644 index ad8d2603..00000000 --- a/bench/bench-libdynamic.c +++ /dev/null @@ -1,170 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include - -// Needed due to compilation error in pool.h -#include - -#include "dynamic.h" - -#include "common.h" - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - vector a1, a2; - - vector_construct(&a1, sizeof(unsigned int)); - vector_construct(&a2, sizeof(unsigned int)); - for(size_t i = 0; i < n; i++) { - unsigned int v = rand_get(); - vector_push_back(&a1, &v); - v = rand_get(); - vector_push_back(&a2, &v); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += *(unsigned int*) vector_at(&a1, i) * *(unsigned int*) vector_at(&a2, i); - } - g_result = s; - vector_destruct(&a1, NULL); - vector_destruct(&a2, NULL); -} - - -/********************************************************************************************/ - -static size_t hash_func (void *a) -{ - return hash_data(a, sizeof (unsigned long)); -} - -static int equal_func(void *a, void *b) -{ - const unsigned long *pa = a; - if (b == NULL) { - return *pa == -1U; - } - const unsigned long *pb = b; - return *pa == *pb; -} - -static void set_func(void *a, void *b) -{ - unsigned long *pa = a; - if (b == NULL) { - *pa = -1U; - } else { - const unsigned long *pb = b; - *pa = *pb; - } -} - -typedef struct map_element map_element; -struct map_element -{ - unsigned long key; - unsigned long value; -}; - -static void -test_dict(size_t n) -{ - map dict; - map_construct(&dict, sizeof(map_element), set_func); - - for (size_t i = 0; i < n; i++) { - map_insert(&dict, (map_element[]) {{.key = rand_get(), .value = rand_get()}}, hash_func, set_func, equal_func, NULL); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - map_element *p = map_at(&dict, (map_element[]){{.key = rand_get()}}, hash_func, equal_func); - if (p) - s += p->value; - } - g_result = s; - map_destruct(&dict, NULL, NULL); -} - -/********************************************************************************************/ - -typedef char char_array_t[256]; - -static int char_equal (void *a, void *b) -{ - const char_array_t *pa = (const char_array_t *)a; - if (b == NULL) - return strcmp(*pa, "") == 0; - const char_array_t *pb = (const char_array_t *)b; - return strcmp(*pa,*pb)==0; -} - -static size_t char_hash(void *a) -{ - char_array_t *pa = (char_array_t *)a; - return hash_string(*pa); -} - -static void char_set(void *a, void *b) -{ - char_array_t *pa = (char_array_t *)a; - if (b == NULL) { - strcpy(*pa, ""); - } else { - const char_array_t *pb = (const char_array_t *)b; - strcpy(*pa,*pb); - } -} - -typedef struct big_map_element big_map_element; -struct big_map_element -{ - char_array_t key; - char_array_t value; -}; - -static void -test_dict_big(size_t n) -{ - map dict; - map_construct(&dict, sizeof(big_map_element), char_set); - - for (size_t i = 0; i < n; i++) { - big_map_element el; - sprintf(el.key, "%u", rand_get()); - sprintf(el.value, "%u", rand_get()); - map_insert(&dict, &el, char_hash, char_set, char_equal, NULL); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - big_map_element el; - sprintf(el.key, "%u", rand_get()); - big_map_element *p = map_at(&dict, &el, char_hash, char_equal); - if (p) - s ++; - } - g_result = s; - map_destruct(&dict, NULL, NULL); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 20, "Array", 100000000, 0, test_array, 0}, - { 40, "dict", 1000000, 0, test_dict, 0}, - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("LIBDYNAMIC", numberof(table), table, argc, argv); - exit(0); - } diff --git a/bench/bench-liblfds.c b/bench/bench-liblfds.c deleted file mode 100644 index 832bfb21..00000000 --- a/bench/bench-liblfds.c +++ /dev/null @@ -1,116 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "liblfds711.h" - -#include "common.h" - -/********************************************************************************************/ - -struct lfds711_queue_bmm_state g_buff; -struct lfds711_queue_bmm_state g_final; - -static void final(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long j, s = 0; - LFDS711_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; - for(int i = 0; i < n;i++) { - void *p; - while (0 == lfds711_queue_bmm_dequeue(&g_final, &p, NULL)) { m_thread_yield(); } - j = (uintptr_t)p; - s += j; - } - g_result = s; -} - -static void conso(void *arg) -{ - unsigned int j; - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long s = 0; - LFDS711_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; - for(int i = 0; i < n;i++) { - void *p; - while (0 == lfds711_queue_bmm_dequeue(&g_buff, &p, NULL)) { m_thread_yield(); } - j = (uintptr_t) p; - s += j; - } - while (0 == lfds711_queue_bmm_enqueue(&g_final, (void*)(uintptr_t)s, NULL)) { m_thread_yield(); } -} - -static void prod(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - size_t r = n; - LFDS711_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; - for(unsigned int i = 0; i < n;i++) { - while (0 == lfds711_queue_bmm_enqueue(&g_buff, (void*)(uintptr_t)r, NULL)) { m_thread_yield(); } - r = r * 31421U + 6927U; - } -} - -static void test_queue(size_t n) -{ - const int cpu_count = get_cpu_count(); - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - if (cpu_count < 2) { - fprintf(stderr, "WARNING: Can not measure Buffer performance.\n"); - return; - } - rand_get(); - // Init - const size_t size = m_core_roundpow2(64*cpu_count); - struct lfds711_queue_bmm_element g_buff_elements[size]; - struct lfds711_queue_bmm_element g_final_elements[size]; - lfds711_queue_bmm_init_valid_on_current_logical_core(&g_buff, g_buff_elements, - size, NULL); - lfds711_queue_bmm_init_valid_on_current_logical_core(&g_final, g_final_elements, - size, NULL); - - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - - // Clear & quit - lfds711_queue_bmm_cleanup(&g_final, NULL); - lfds711_queue_bmm_cleanup(&g_buff, NULL); -} - - -/********************************************************************************************/ - -const config_func_t table[] = { - { 60, "Queue MPMC", 1000000, 0, test_queue, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("LIBLFDS", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-libsrt.c b/bench/bench-libsrt.c deleted file mode 100644 index 0da2b672..00000000 --- a/bench/bench-libsrt.c +++ /dev/null @@ -1,74 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "svector.h" -#include "smap.h" -#include "smset.h" - -#include "common.h" - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - srt_vector *a1 = sv_alloc ( sizeof (unsigned int), 16, NULL); - srt_vector *a2 = sv_alloc ( sizeof (unsigned int), 16, NULL); - - for(size_t i = 0; i < n; i++) { - unsigned int value = rand_get(); - sv_push(&a1, &value ); - value = rand_get(); - sv_push(&a2, &value ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += *(unsigned int*)sv_at(a1, i ) * *(unsigned int *)sv_at(a2, i ); - } - g_result = s; - - sv_free(&a1); - sv_free(&a2); -} - -/********************************************************************************************/ - -/* There is no 'unsigned long' key in smset */ - -/********************************************************************************************/ - -static int cmp_float (const void *a, const void *b) -{ - const float *pa=a; - const float *pb = b; - return (*pa < *pb) ? -1 : *pa > *pb; -} - -static void test_sort(size_t n) -{ - srt_vector *a1 = sv_alloc(sizeof(float), 16, cmp_float); - for(size_t i = 0; i < n; i++) { - unsigned int value = rand_get(); - sv_push(&a1, &value ); - } - sv_sort(a1); - g_result = *(float*)sv_at(a1, 0); - sv_free(&a1); -} - -/********************************************************************************************/ - - -const config_func_t table[] = { - { 20, "Array", 100000000, 0, test_array, 0}, - { 50, "sort", 10000000, 0, test_sort, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("LIBSRT", numberof(table), table, argc, argv); - exit(0); -} - diff --git a/bench/bench-mlib.c b/bench/bench-mlib.c deleted file mode 100644 index 0947a382..00000000 --- a/bench/bench-mlib.c +++ /dev/null @@ -1,1086 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "m-array.h" -#include "m-list.h" -#include "m-rbtree.h" -#include "m-bptree.h" -#include "m-deque.h" -#include "m-dict.h" -#include "m-algo.h" -#include "m-mempool.h" -#include "m-string.h" -#include "m-buffer.h" -#include "m-thread.h" -#include "m-deque.h" -#include "m-concurrent.h" -#include "m-tuple.h" -#include "m-serial-bin.h" -#include "m-serial-json.h" - -#include "common.h" - -/********************************************************************************************/ - -ARRAY_DEF(array_uint, unsigned int) - -static void test_array(size_t n) -{ - M_LET(a1, a2, ARRAY_OPLIST(array_uint)) { - for(size_t i = 0; i < n; i++) { - array_uint_push_back(a1, rand_get() ); - array_uint_push_back(a2, rand_get() ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += *array_uint_cget(a1, i ) * *array_uint_cget(a2, i ); - } - g_result = s; - } -} - -/********************************************************************************************/ - -DEQUE_DEF(deque_uint, unsigned int) - -static void test_deque(size_t n) -{ - M_LET(a1, a2, DEQUE_OPLIST(deque_uint)) { - for(size_t i = 0; i < n; i++) { - deque_uint_push_back(a1, rand_get() ); - deque_uint_push_back(a2, rand_get() ); - } - unsigned int s = 0; - deque_uint_it_t it1, it2; - for(deque_uint_it(it1, a1), deque_uint_it(it2, a2) ; !deque_uint_end_p(it1) ; deque_uint_next(it1), deque_uint_next(it2)) { - s += *deque_uint_cref(it1 ) * *deque_uint_cref(it2 ); - } - g_result = s; - } -} - -/********************************************************************************************/ - -// Two benched mode: with or without mempool -#ifdef USE_MEMPOOL -LIST_DEF(list_uint, unsigned int, (MEMPOOL( list_mpool), MEMPOOL_LINKAGE(static))) -#else -LIST_DEF(list_uint, unsigned int) -#endif - -static void test_list (size_t n) -{ -#ifdef USE_MEMPOOL - list_uint_mempool_init(list_mpool); -#endif - M_LET(a1, a2, LIST_OPLIST(list_uint)) { - 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; - list_uint_it_t it1, it2; - for(list_uint_it(it1, a1), list_uint_it(it2,a2); !list_uint_end_p(it1); list_uint_next(it1), list_uint_next(it2)) { - s += *list_uint_cref(it1) * *list_uint_cref(it2); - } - g_result = s; - } -#ifdef USE_MEMPOOL - list_uint_mempool_clear(list_mpool); -#endif -} - -/********************************************************************************************/ - -// Two benched mode: with or without mempool -#ifdef USE_MEMPOOL -LIST_DUAL_PUSH_DEF(dlist_uint, unsigned int, (MEMPOOL( dlist_mpool), MEMPOOL_LINKAGE(static))) -#else -LIST_DUAL_PUSH_DEF(dlist_uint, unsigned int) -#endif - -static void test_dlist (size_t n) -{ -#ifdef USE_MEMPOOL - dlist_uint_mempool_init(dlist_mpool); -#endif - M_LET(a1, a2, LIST_OPLIST(dlist_uint)) { - for(size_t i = 0; i < n; i++) { - dlist_uint_push_back(a1, rand_get() ); - dlist_uint_push_back(a2, rand_get() ); - } - unsigned int s = 0; - dlist_uint_it_t it1, it2; - for(dlist_uint_it(it1, a1), dlist_uint_it(it2,a2); !dlist_uint_end_p(it1); dlist_uint_next(it1), dlist_uint_next(it2)) { - s += *dlist_uint_cref(it1) * *dlist_uint_cref(it2); - } - g_result = s; - } -#ifdef USE_MEMPOOL - dlist_uint_mempool_clear(dlist_mpool); -#endif -} - -/********************************************************************************************/ - -#ifdef USE_MEMPOOL -RBTREE_DEF(rbtree_ulong, unsigned long, (MEMPOOL( rbtree_mpool), MEMPOOL_LINKAGE(static))) -#else -RBTREE_DEF(rbtree_ulong, unsigned long) -#endif - -static void test_rbtree(size_t n) -{ -#ifdef USE_MEMPOOL - rbtree_ulong_mempool_init(rbtree_mpool); -#endif - M_LET(tree, RBTREE_OPLIST(rbtree_ulong)) { - for (size_t i = 0; i < n; i++) { - rbtree_ulong_push(tree, rand_get()); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long *p = rbtree_ulong_get(tree, rand_get()); - if (p) - s += *p; - } - g_result = s; - } -#ifdef USE_MEMPOOL - rbtree_ulong_mempool_clear(rbtree_mpool); -#endif -} - -/********************************************************************************************/ - -BPTREE_DEF(bptree_ulong, 21, unsigned long, M_DEFAULT_OPLIST) - -static void test_bptree(size_t n) -{ - M_LET(tree, BPTREE_OPLIST(bptree_ulong)) { - for (size_t i = 0; i < n; i++) { - bptree_ulong_push(tree, rand_get()); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long *p = bptree_ulong_get(tree, rand_get()); - if (p) - s += *p; - } - g_result = s; - } -} - -/********************************************************************************************/ - -#ifdef USE_MEMPOOL -DICT_DEF2(dict_ulong, unsigned long, M_OPEXTEND(M_DEFAULT_OPLIST, MEMPOOL(dict_mpool), MEMPOOL_LINKAGE(static)), unsigned long, M_DEFAULT_OPLIST) -#else -DICT_DEF2(dict_ulong, unsigned long, M_DEFAULT_OPLIST, unsigned long, M_DEFAULT_OPLIST) -#endif - -static void -test_dict(size_t n) -{ -#ifdef USE_MEMPOOL - dict_ulong_list_pair_mempool_init(dict_mpool); -#endif - M_LET(dict, DICT_OPLIST(dict_ulong)) { - for (size_t i = 0; i < n; i++) { - unsigned long value = rand_get(); - unsigned long key = rand_get(); - dict_ulong_set_at(dict, key, value); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long *p = dict_ulong_get(dict, rand_get()); - if (p) - s += *p; - } - g_result = s; - } -#ifdef USE_MEMPOOL - dict_ulong_list_pair_mempool_clear(dict_mpool); -#endif -} - -/********************************************************************************************/ - -static inline bool oor_equal_p(unsigned long k, unsigned char n) -{ - return k == (unsigned long)n; -} - -static inline void oor_set(unsigned long *k, unsigned char n) -{ - *k = (unsigned long)n; -} - -DICT_OA_DEF2(dict_oa_ulong, - unsigned long, M_OPEXTEND(M_DEFAULT_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)), - unsigned long, M_DEFAULT_OPLIST) - -static void -test_dict_oa(size_t n) -{ - M_LET(dict, DICT_OPLIST(dict_oa_ulong)) { - for (size_t i = 0; i < n; i++) { - dict_oa_ulong_set_at(dict, rand_get(), rand_get() ); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long *p = dict_oa_ulong_get(dict, rand_get()); - if (p) - s += *p; - } - g_result = s; - } -} - -static void -test_dict_oa_linear(size_t n) -{ - M_LET(dict, DICT_OPLIST(dict_oa_ulong)) { - for (size_t i = 0; i < n; i++) { - dict_oa_ulong_set_at(dict, i, rand_get() ); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long *p = dict_oa_ulong_get(dict, i); - if (p) - s += *p; - } - g_result = s; - } -} - -/********************************************************************************************/ -#ifndef CHAR_ARRAY_SIZE -#define CHAR_ARRAY_SIZE 256 -#endif -typedef char char_array_t[CHAR_ARRAY_SIZE]; -static void char_init (char_array_t a) { a[0] = 0; } -static void char_set (char_array_t a, const char_array_t b) { strcpy(a, b); } -static bool char_equal_p (const char_array_t a, const char_array_t b) { return strcmp(a,b)==0; } -static size_t char_hash(const char_array_t a) { return m_core_hash (a, strlen(a)); } -static bool char_oor_equal_p(const char_array_t a, unsigned char n) { return a[0] == 1+n; } -static void char_oor_set(char_array_t a, unsigned char n) { a[0] = 1+n; } -#define M_OPL_char_array_t() (INIT(char_init), INIT_SET(char_set), SET(char_set), CLEAR(char_init), HASH(char_hash), EQUAL(char_equal_p), OOR_EQUAL(char_oor_equal_p), OOR_SET(char_oor_set)) - -#ifdef USE_MEMPOOL -DICT_STOREHASH_DEF2(dict_char, char_array_t, M_OPEXTEND(M_OPL_char_array_t(),MEMPOOL(dict_mpool2), MEMPOOL_LINKAGE(static)), char_array_t, M_OPL_char_array_t()) -#else -DICT_STOREHASH_DEF2(dict_char, char_array_t, M_OPL_char_array_t(), char_array_t, M_OPL_char_array_t()) -#endif - - -static void -test_dict_big(size_t n) -{ -#ifdef USE_MEMPOOL - dict_char_list_pair_mempool_init(dict_mpool2); -#endif - M_LET(dict, DICT_OPLIST(dict_char)) { - for (size_t i = 0; i < n; i++) { - char_array_t s1, s2; - sprintf(s1, "%u", rand_get()); - sprintf(s2, "%u", rand_get()); - dict_char_set_at(dict, s1, s2); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_t s1; - sprintf(s1, "%u", rand_get()); - char_array_t *p = dict_char_get(dict, s1); - if (p) - s ++; - } - g_result = s; - } -#ifdef USE_MEMPOOL - dict_char_list_pair_mempool_clear(dict_mpool2); -#endif -} - -DICT_OA_DEF2(dict_oa_char, char_array_t, char_array_t) - -static void -test_dict_oa_big(size_t n) -{ - M_LET(dict, DICT_OPLIST(dict_oa_char)) { - for (size_t i = 0; i < n; i++) { - char_array_t s1, s2; - sprintf(s1, "%u", rand_get()); - sprintf(s2, "%u", rand_get()); - dict_oa_char_set_at(dict, s1, s2); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_t s1; - sprintf(s1, "%u", rand_get()); - char_array_t *p = dict_oa_char_get(dict, s1); - if (p) - s ++; - } - g_result = s; - } -} - -/********************************************************************************************/ - -#ifdef USE_MEMPOOL -DICT_DEF2(dict_str, string_t, M_OPEXTEND(STRING_OPLIST, MEMPOOL(dict_mpool3), MEMPOOL_LINKAGE(static)), string_t, STRING_OPLIST) -#else -DICT_DEF2(dict_str, string_t, STRING_OPLIST, string_t, STRING_OPLIST) -#endif - -static void -test_dict_str(size_t n) -{ -#ifdef USE_MEMPOOL - dict_str_list_pair_mempool_init(dict_mpool3); -#endif - M_LET(s1, s2, STRING_OPLIST) - M_LET(dict, DICT_OPLIST(dict_str)) { - for (size_t i = 0; i < n; i++) { - string_printf(s1, "%u", rand_get()); - string_printf(s2, "%u", rand_get()); - dict_str_set_at(dict, s1, s2); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string_printf(s1, "%u", rand_get()); - string_t *p = dict_str_get(dict, s1); - if (p) - s ++; - } - g_result = s; - } -#ifdef USE_MEMPOOL - dict_str_list_pair_mempool_clear(dict_mpool3); -#endif -} - -/********************************************************************************************/ - -ARRAY_DEF(array_float, float) -ALGO_DEF(array_float, ARRAY_OPLIST(array_float)) - -static void test_sort(size_t n) -{ - M_LET(a1, ARRAY_OPLIST(array_float)) { - for(size_t i = 0; i < n; i++) { - array_float_push_back(a1, rand_get() ); - } - array_float_sort(a1); - g_result = *array_float_get(a1, 0); - } -} - -static void test_stable_sort(size_t n) -{ - M_LET(a1, ARRAY_OPLIST(array_float)) { - for(size_t i = 0; i < n; i++) { - array_float_push_back(a1, rand_get() ); - } - array_float_special_stable_sort(a1); - g_result = *array_float_get(a1, 0); - } -} - -/********************************************************************************************/ - -#define SIZE_LIMIT (UINT_MAX/2) - -BUFFER_DEF(buffer_uint, unsigned int, 0, BUFFER_QUEUE|BUFFER_BLOCKING) -buffer_uint_t g_buff_lock; - -BUFFER_DEF(buffer_ull, unsigned long long, 0, BUFFER_QUEUE|BUFFER_BLOCKING) -buffer_ull_t g_final_lock; - -static void final_lock(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long j, s = 0; - for(int i = 0; i < n;i++) { - buffer_ull_pop(&j, g_final_lock); - s += j; - } - g_result = s; -} - -static void conso_lock(void *arg) -{ - unsigned int j; - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long s = 0; - for(int i = 0; i < n;i++) { - buffer_uint_pop(&j, g_buff_lock); - s += j; - } - buffer_ull_push(g_final_lock, s); -} - -static void prod_lock(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - size_t r = n; - for(unsigned int i = 0; i < n;i++) { - buffer_uint_push(g_buff_lock, r ); - r = r * 31421U + 6927U; - } -} - -static void test_buffer(size_t n) -{ - const int cpu_count = n > SIZE_LIMIT ? 2 : get_cpu_count(); - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - if (cpu_count < 2) { - fprintf(stderr, "WARNING: Can not measure Buffer performance.\n"); - return; - } - n = n > SIZE_LIMIT ? n - SIZE_LIMIT : n; - // Init - buffer_uint_init(g_buff_lock, 64*cpu_count); - buffer_ull_init (g_final_lock, 64*cpu_count); - - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod_lock, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso_lock, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final_lock, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - - // Clear & quit - buffer_ull_clear(g_final_lock); - buffer_uint_clear(g_buff_lock); -} - -/********************************************************************************************/ - -QUEUE_MPMC_DEF(queue_uint, unsigned int, BUFFER_QUEUE) -queue_uint_t g_buff_mpmc; - -QUEUE_MPMC_DEF(queue_ull, unsigned long long, BUFFER_QUEUE) -queue_ull_t g_final_mpmc; - -static void final_mpmc(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long j, s = 0; - for(int i = 0; i < n;i++) { - while (!queue_ull_pop(&j, g_final_mpmc)) m_thread_yield(); - s += j; - } - g_result = s; -} - -static void conso_mpmc(void *arg) -{ - unsigned int j; - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long s = 0; - for(int i = 0; i < n;i++) { - while (!queue_uint_pop(&j, g_buff_mpmc)) m_thread_yield(); - s += j; - } - while (!queue_ull_push(g_final_mpmc, s)); -} - -static void prod_mpmc(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - size_t r = n; - for(unsigned int i = 0; i < n;i++) { - while (!queue_uint_push(g_buff_mpmc, r )) m_thread_yield(); - r = r * 31421U + 6927U; - } -} - -static void test_queue(size_t n) -{ - const int cpu_count = n > SIZE_LIMIT ? 2 : get_cpu_count(); - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - if (cpu_count < 2) { - fprintf(stderr, "WARNING: Can not measure Queue performance.\n"); - return; - } - n = n > SIZE_LIMIT ? n - SIZE_LIMIT : n; - // Init - queue_uint_init(g_buff_mpmc, 64*cpu_count); - queue_ull_init (g_final_mpmc, 64*cpu_count); - - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod_mpmc, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso_mpmc, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final_mpmc, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - - // Clear & quit - queue_ull_clear(g_final_mpmc); - queue_uint_clear(g_buff_mpmc); -} - -/********************************************************************************************/ - -QUEUE_SPSC_DEF(queue_single_uint, unsigned int, BUFFER_QUEUE) -queue_single_uint_t g_buff_spsc; - -QUEUE_SPSC_DEF(queue_single_ull, unsigned long long, BUFFER_QUEUE) -queue_single_ull_t g_final_spsc; - -static void final_spsc(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long j, s = 0; - for(int i = 0; i < n;i++) { - while (!queue_single_ull_pop(&j, g_final_spsc)) m_thread_yield(); - s += j; - } - g_result = s; -} - -static void conso_spsc(void *arg) -{ - unsigned int j; - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long s = 0; - for(int i = 0; i < n;i++) { - while (!queue_single_uint_pop(&j, g_buff_spsc)) m_thread_yield(); - s += j; - } - while (!queue_single_ull_push(g_final_spsc, s)); -} - -static void prod_spsc(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - size_t r = n; - for(unsigned int i = 0; i < n;i++) { - while (!queue_single_uint_push(g_buff_spsc, r )) m_thread_yield(); - r = r * 31421U + 6927U; - } -} - -static void test_queue_single(size_t n) -{ - const int cpu_count = 2; - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - // Init - queue_single_uint_init(g_buff_spsc, 64*cpu_count); - queue_single_ull_init (g_final_spsc, 64*cpu_count); - - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod_spsc, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso_spsc, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final_spsc, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - - // Clear & quit - queue_single_ull_clear(g_final_spsc); - queue_single_uint_clear(g_buff_spsc); -} - -/********************************************************************************************/ - -#define BULK_SIZE 20 - -static void final_spsc_bulk(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long j, s = 0; - for(int i = 0; i < n;i++) { - while (!queue_single_ull_pop(&j, g_final_spsc)) m_thread_yield(); - s += j; - } - g_result = s; -} - -static void conso_spsc_bulk(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long s = 0; - unsigned tab[BULK_SIZE]; - for(int i = 0; i < n;i+= BULK_SIZE) { - unsigned k = queue_single_uint_pop_bulk(BULK_SIZE, tab, g_buff_spsc); - while (k != BULK_SIZE) { - m_thread_yield(); - k += queue_single_uint_pop_bulk(BULK_SIZE-k, tab+k, g_buff_spsc); - } - for(k = 0; k < BULK_SIZE;k++) - s += tab[k]; - } - while (!queue_single_ull_push(g_final_spsc, s)); -} - -static void prod_spsc_bulk(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - if ((n % BULK_SIZE) != 0) abort(); - size_t r = n; - unsigned tab[BULK_SIZE]; - for(unsigned int i = 0; i < n;i+= BULK_SIZE) { - for(unsigned k = 0; k < BULK_SIZE; k++) { - tab[k] = r; - r = r * 31421U + 6927U; - } - unsigned k = queue_single_uint_push_bulk(g_buff_spsc, BULK_SIZE, tab); - while (k != BULK_SIZE) { - m_thread_yield(); - k += queue_single_uint_push_bulk(g_buff_spsc, BULK_SIZE-k, tab+k); - } - } -} - -static void test_queue_single_bulk(size_t n) -{ - const int cpu_count = 2; - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - // Init - queue_single_uint_init(g_buff_spsc, 64*cpu_count); - queue_single_ull_init (g_final_spsc, 64*cpu_count); - - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod_spsc_bulk, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso_spsc_bulk, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final_spsc_bulk, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - - // Clear & quit - queue_single_ull_clear(g_final_spsc); - queue_single_uint_clear(g_buff_spsc); -} - -/********************************************************************************************/ - -CONCURRENT_DEF(cdeque_uint, deque_uint_t, M_OPEXTEND(DEQUE_OPLIST(deque_uint, M_DEFAULT_OPLIST), PUSH(deque_uint_push_front))) - -DEQUE_DEF(deque_ull, unsigned long long) -CONCURRENT_DEF(cdeque_ull, deque_ull_t, M_OPEXTEND(DEQUE_OPLIST(deque_ull, M_DEFAULT_OPLIST), PUSH(deque_ull_push_front))) - -cdeque_uint_t g_buff_conc; -cdeque_ull_t g_final_conc; - -static void final_conc(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long j, s = 0; - for(int i = 0; i < n;i++) { - cdeque_ull_pop_blocking(&j, g_final_conc, true); - s += j; - } - g_result = s; -} - -static void conso_conc(void *arg) -{ - unsigned int j; - size_t *p_n = arg; - size_t n = *p_n; - unsigned long long s = 0; - for(int i = 0; i < n;i++) { - cdeque_uint_pop_blocking(&j, g_buff_conc, true); - s += j; - } - cdeque_ull_push(g_final_conc, s); -} - -static void prod_conc(void *arg) -{ - size_t *p_n = arg; - size_t n = *p_n; - size_t r = n; - for(unsigned int i = 0; i < n;i++) { - cdeque_uint_push(g_buff_conc, r ); - r = r * 31421U + 6927U; - } -} - -static void test_queue_concurrent(size_t n) -{ - const int cpu_count = n > SIZE_LIMIT ? 2 : get_cpu_count(); - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - if (cpu_count < 2) { - fprintf(stderr, "WARNING: Can not measure CONCURRENT performance.\n"); - return; - } - n = n > SIZE_LIMIT ? n - SIZE_LIMIT : n; - // Init - cdeque_uint_init(g_buff_conc); - cdeque_ull_init (g_final_conc); - - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod_conc, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso_conc, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final_conc, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - - // Clear & quit - cdeque_ull_clear(g_final_conc); - cdeque_uint_clear(g_buff_conc); -} - -/********************************************************************************************/ - -static unsigned long *g_p; - -static void test_hash_prepare(size_t n) -{ - g_p = malloc (n * sizeof(unsigned long)); - if (g_p == NULL) abort(); - for(size_t i = 0; i < n ; i++) - g_p[i] = ((rand_get()*RAND_MAX + rand_get())*RAND_MAX+rand_get())*RAND_MAX + rand_get(); -} - - -static void test_hash_final(void) -{ - free(g_p); -} - -static void test_hash(size_t n) -{ - M_HASH_DECL(hash); - for(size_t i = 0; i < n; i++) - M_HASH_UP(hash, g_p[i]); - g_result = M_HASH_FINAL(hash); -} - -static void test_core_hash(size_t n) -{ - g_result = m_core_hash(g_p, n*sizeof(unsigned long)); -} - - -/********************************************************************************************/ - -ARRAY_DEF(vector_string, string_t) - -vector_string_t vstring; -vector_string_t vstring2; - -static void -bench_vector_string_init(size_t n) -{ - vector_string_init(vstring); - for(size_t i = 0; i < n; i++) - { - M_LET( (s, "%zu", i), string_t) { - vector_string_push_back(vstring, s); - } - } - vector_string_init(vstring2); -} - -static void -bench_vector_string_init_big(size_t n) -{ - vector_string_init(vstring); - for(size_t i = 0; i < n; i++) - { - M_LET( (s, "%zu%zu%zu%zu%zu%zu", i, i, i, i, i, i), string_t) { - vector_string_push_back(vstring, s); - } - } - vector_string_init(vstring2); -} - -static void -bench_vector_string_bin_run(size_t n) -{ - if (vector_string_size(vstring) != n) { - fprintf(stderr, "ERROR: Size are different (%zu vs %zu)!\n", n, vector_string_size(vstring)); - abort(); - } - - FILE *f = fopen("tmp-serial.dat", "wb"); - if (!f) abort(); - M_LET( (serial, f), m_serial_bin_write_t) { - vector_string_out_serial(serial, vstring); - } - fclose(f); - - f = fopen("tmp-serial.dat", "rb"); - if (!f) abort(); - M_LET( (serial, f), m_serial_bin_read_t) { - vector_string_in_serial(vstring2, serial); - } - fclose(f); - - if (vector_string_size(vstring2) != n) { - fprintf(stderr, "ERROR: Size are different (%zu vs %zu)!\n", n, vector_string_size(vstring2)); - abort(); - } -} - -static void -bench_vector_string_json_run(size_t n) -{ - if (vector_string_size(vstring) != n) { - fprintf(stderr, "ERROR: Size are different (%zu vs %zu)!\n", n, vector_string_size(vstring)); - abort(); - } - - FILE *f = fopen("tmp-serial.json", "wt"); - if (!f) abort(); - M_LET( (serial, f), m_serial_json_write_t) { - vector_string_out_serial(serial, vstring); - } - fclose(f); - - f = fopen("tmp-serial.json", "rt"); - if (!f) abort(); - M_LET( (serial, f), m_serial_json_read_t) { - vector_string_in_serial(vstring2, serial); - } - fclose(f); - - if (vector_string_size(vstring2) != n) { - fprintf(stderr, "ERROR: Size are different (%zu vs %zu)!\n", n, vector_string_size(vstring2)); - abort(); - } -} - -static void -bench_vector_string_clear(void) -{ - if (!vector_string_equal_p(vstring, vstring2)) { - fprintf(stderr, "ERROR: Array are different after deserialization!\n"); - abort(); - } - vector_string_clear(vstring); - vector_string_clear(vstring2); -} - -/********************************************************************************************/ - -ARRAY_DEF(vector_ulong, unsigned long) - -vector_ulong_t vulong; -vector_ulong_t vulong2; - -static void -bench_vector_ulong_init(size_t n) -{ - vector_ulong_init(vulong); - for(size_t i = 0; i < n; i++) - { - vector_ulong_push_back(vulong, i*i); - } - vector_ulong_init(vulong2); -} - -static void -bench_vector_ulong_bin_run(size_t n) -{ - if (vector_ulong_size(vulong) != n) { - fprintf(stderr, "ERROR: Size are different!\n"); - abort(); - } - - FILE *f = fopen("tmp-serial.dat", "wb"); - if (!f) abort(); - M_LET( (serial, f), m_serial_bin_write_t) { - vector_ulong_out_serial(serial, vulong); - } - fclose(f); - - f = fopen("tmp-serial.dat", "rb"); - if (!f) abort(); - M_LET( (serial, f), m_serial_bin_read_t) { - vector_ulong_in_serial(vulong2, serial); - } - fclose(f); - - if (vector_ulong_size(vulong2) != n) { - fprintf(stderr, "ERROR: Size are different!\n"); - abort(); - } -} - -static void -bench_vector_ulong_json_run(size_t n) -{ - if (vector_ulong_size(vulong) != n) { - fprintf(stderr, "ERROR: Size are different!\n"); - abort(); - } - - FILE *f = fopen("tmp-serial.json", "wt"); - if (!f) abort(); - M_LET( (serial, f), m_serial_json_write_t) { - vector_ulong_out_serial(serial, vulong); - } - fclose(f); - - f = fopen("tmp-serial.json", "rt"); - if (!f) abort(); - M_LET( (serial, f), m_serial_json_read_t) { - vector_ulong_in_serial(vulong2, serial); - } - fclose(f); - - if (vector_ulong_size(vulong2) != n) { - fprintf(stderr, "ERROR: Size are different!\n"); - abort(); - } -} - -static void -bench_vector_ulong_clear(void) -{ - if (!vector_ulong_equal_p(vulong, vulong2)) { - fprintf(stderr, "ERROR: Array are different after deserialization!\n"); - abort(); - } - vector_ulong_clear(vulong); - vector_ulong_clear(vulong2); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 11, "DPList", 10000000, 0, test_dlist, 0}, - { 20, "Array", 100000000, 0, test_array, 0}, - { 21, "Deque", 100000000, 0, test_deque, 0}, - { 30, "Rbtree", 1000000, 0, test_rbtree, 0}, - { 31, "B+tree", 1000000, 0, test_bptree, 0}, - { 40, "dict", 1000000, 0, test_dict, 0}, - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict(OA)", 1000000, 0, test_dict_oa, 0}, - { 43,"DictStr", 1000000, 0, test_dict_str, 0}, - { 46, "dictLinear(OA)", 1000000, 0, test_dict_oa_linear, 0}, - { 47, "dictBig(OA)", 1000000, 0, test_dict_oa_big, 0}, - { 50, "Sort",10000000, 0, test_sort, 0}, - { 51, "Stable Sort",10000000, 0, test_stable_sort, 0}, - { 60,"Buffer", 1000000, 0, test_buffer, 0}, - { 61,"Queue MPMC", 1000000, 0, test_queue, 0}, - { 62,"Buffer(P=2)", SIZE_LIMIT+1000000, 0, test_buffer, 0}, - { 63,"Queue MPMC (P=2)", SIZE_LIMIT+1000000, 0, test_queue, 0}, - { 64,"Queue SPSC (P=2)", 1000000, 0, test_queue_single, 0}, - { 65,"Queue Concurrent", 1000000, 0, test_queue_concurrent, 0}, - { 66,"Queue SPSC(Bulk)", 1000000, 0, test_queue_single_bulk, 0}, - { 70,"M_HASH", 100000000, test_hash_prepare, test_hash, test_hash_final}, - { 71,"Core Hash", 100000000, test_hash_prepare, test_core_hash, test_hash_final}, - {100, "serial-bin STR", 10000000, bench_vector_string_init, bench_vector_string_bin_run, bench_vector_string_clear}, - {101, "serial-bin STR.big", 10000000, bench_vector_string_init_big, bench_vector_string_bin_run, bench_vector_string_clear}, - {102, "serial-bin INT", 10000000, bench_vector_ulong_init, bench_vector_ulong_bin_run, bench_vector_ulong_clear}, - {110, "serial-json STR", 10000000, bench_vector_string_init, bench_vector_string_json_run, bench_vector_string_clear}, - {111, "serial-json STR.big", 10000000, bench_vector_string_init_big, bench_vector_string_json_run, bench_vector_string_clear}, - {112, "serial-json INT", 10000000, bench_vector_ulong_init, bench_vector_ulong_json_run, bench_vector_ulong_clear} -}; - -int main(int argc, const char *argv[]) -{ - test("M*LIB", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-nedtries.c b/bench/bench-nedtries.c deleted file mode 100644 index 5024ec7f..00000000 --- a/bench/bench-nedtries.c +++ /dev/null @@ -1,99 +0,0 @@ -#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(size_t 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(size_t 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); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 40, "dict", 1000000, 0, test_dict, 0}, - { 45, "dict(noalloc)", 1000000, 0, test_dict_noalloc, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("NEDTRIES", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-plain-c.c b/bench/bench-plain-c.c deleted file mode 100644 index 6aad663d..00000000 --- a/bench/bench-plain-c.c +++ /dev/null @@ -1,90 +0,0 @@ -// Inspired by: http://stackoverflow.com/questions/3664272/is-stdvector-so-much-slower-than-plain-arrays/3664349#3664349 - -#define NDEBUG - -#include -#include -#include -#include -#include -#include - -#include "m-array.h" -#include "m-list.h" -#include "m-rbtree.h" -#include "m-dict.h" -#include "m-algo.h" -#include "m-mempool.h" -#include "m-string.h" - -unsigned long g_result; - -static unsigned long long -cputime (void) -{ - struct rusage rus; - getrusage (0, &rus); - return rus.ru_utime.tv_sec * 1000000ULL + rus.ru_utime.tv_usec; -} - -struct Pixel -{ - unsigned char r, g, b; -}; - -ARRAY_DEF(array_pixel, struct Pixel, (INIT(M_NOTHING_DEFAULT), INIT_SET(M_MEMCPY_DEFAULT) )) - -void UseMlib(void) -{ - unsigned long long t1 = cputime(); - - for(int i = 0; i < 1000; ++i) - { - int dimension = 999; - - array_pixel_t pixels; - array_pixel_init(pixels); - array_pixel_reserve(pixels, dimension * dimension); - - for(int i = 0; i < dimension * dimension; ++i) - { - const struct Pixel p = { 255, 0, 0}; - array_pixel_push_back (pixels, p); - } - - array_pixel_clear(pixels); - } - unsigned long long t2 = cputime(); - printf ("M*Lib Array: %Lu us\n", (t2-t1)/1000); -} - -void UseNative(void) -{ - unsigned long long t1 = cputime(); - - for(int i = 0; i < 1000; ++i) - { - int dimension = 999; - - struct Pixel * pixels = malloc(sizeof(struct Pixel) * dimension * dimension); - - for(int i = 0 ; i < dimension * dimension; ++i) - { - pixels[i].r = 255; - pixels[i].g = 0; - pixels[i].b = 0; - } - - free(pixels); - } - unsigned long long t2 = cputime(); - printf ("Native Array: %Lu us\n", (t2-t1)/1000); -} - -int main(void) -{ - UseNative(); - UseMlib(); - - return 0; -} diff --git a/bench/bench-pottery.c b/bench/bench-pottery.c deleted file mode 100644 index edd08b5b..00000000 --- a/bench/bench-pottery.c +++ /dev/null @@ -1,269 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "common.h" - -/********************************************************************************************/ - -#define POTTERY_VECTOR_PREFIX vec_uint -#define POTTERY_VECTOR_VALUE_TYPE unsigned int -#define POTTERY_VECTOR_LIFECYCLE_BY_VALUE 1 -#include "pottery/vector/pottery_vector_static.t.h" - -static void test_array(size_t n) -{ - vec_uint_t a1, a2; - - vec_uint_init(&a1); - vec_uint_init(&a2); - - for(size_t i = 0; i < n; i++) { - vec_uint_insert_last(&a1, rand_get() ); - vec_uint_insert_last(&a2, rand_get() ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += *vec_uint_at(&a1, i ) * *vec_uint_at(&a2, i ); - } - g_result = s; - - vec_uint_destroy(&a1); - vec_uint_destroy(&a2); -} - -/********************************************************************************************/ - -typedef struct foo_s { - struct foo_s* next; - struct foo_s* previous; - int data; -} foo_t; - -#define POTTERY_DOUBLY_LINKED_LIST_PREFIX foo_list -#define POTTERY_DOUBLY_LINKED_LIST_VALUE_TYPE foo_t -#include "pottery/doubly_linked_list/pottery_doubly_linked_list_static.t.h" - -static void test_list(size_t n) -{ - foo_list_t a1, a2; - foo_list_init(&a1); - foo_list_init(&a2); - for(size_t i = 0; i < n; i++) { - foo_t *tmp = malloc(sizeof (foo_t)); - if (tmp == NULL) abort(); - tmp->data = rand_get(); - foo_list_link_last(&a1, tmp); - - tmp = malloc(sizeof (foo_t)); - if (tmp == NULL) abort(); - tmp->data = rand_get(); - foo_list_link_last(&a2, tmp); - } - unsigned int s = 0; - for(foo_t *it1 = foo_list_first(&a1), *it2 = foo_list_first(&a2) ; - foo_list_entry_exists(&a1, it1) ; - it1 = foo_list_next(&a1, it1), it2 = foo_list_next(&a2, it2)) { - s += it1->data * it2->data; - } - g_result = s; - - for(foo_t *it1 = foo_list_first(&a1); - foo_list_entry_exists(&a1, it1) ; - ) { - foo_t *tmp = it1; - it1 = foo_list_next(&a1, it1); - free(tmp); - } - - for(foo_t *it1 = foo_list_first(&a2); - foo_list_entry_exists(&a2, it1) ; - ) { - foo_t *tmp = it1; - it1 = foo_list_next(&a2, it1); - free(tmp); - } - -} - -/********************************************************************************************/ - -// ERROR: it returns the wrong result. -#define POTTERY_TREE_MAP_PREFIX set_ulong -#define POTTERY_TREE_MAP_VALUE_TYPE unsigned long -#define POTTERY_TREE_MAP_LIFECYCLE_MOVE_BY_VALUE 1 -#define POTTERY_TREE_MAP_COMPARE_THREE_WAY(a,b) ((a) < (b) ? -1 : (a) > (b)) -#define POTTERY_TREE_MAP_LIFECYCLE_DESTROY(a) (void) a -#include "pottery/tree_map/pottery_tree_map_static.t.h" - -static void test_rbtree(size_t n) -{ - set_ulong_t tree; - set_ulong_init(&tree); - - for (size_t i = 0; i < n; i++) { - set_ulong_insert(&tree, rand_get() ); - } - - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long j = rand_get(); - if (set_ulong_find(&tree, &j ) != NULL) - s += j; - } - g_result = s; - set_ulong_destroy(&tree); -} - - -/********************************************************************************************/ - -#include "m-core.h" // For M_HASH_DEFAULT -typedef struct bar_s { - unsigned long key; - unsigned long value; -} bar_t; - -#define POTTERY_OPEN_HASH_MAP_PREFIX map_ulong - -#define POTTERY_OPEN_HASH_MAP_VALUE_TYPE bar_t -#define POTTERY_OPEN_HASH_MAP_KEY_TYPE unsigned long -#define POTTERY_OPEN_HASH_MAP_REF_KEY(v) v->key -#define POTTERY_OPEN_HASH_MAP_KEY_HASH(x) M_HASH_DEFAULT(x) -#define POTTERY_OPEN_HASH_MAP_KEY_EQUAL(x, y) x == y -#define POTTERY_OPEN_HASH_MAP_LIFECYCLE_MOVE(p,q) memcpy(p, q, sizeof (bar_t)) - -#include "pottery/open_hash_map/pottery_open_hash_map_static.t.h" - -static void -test_dict(size_t n) -{ - map_ulong_t dict; - map_ulong_init(&dict); - - for (size_t i = 0; i < n; i++) { - unsigned long value = rand_get(); - unsigned long key = rand_get(); - bar_t * kyle = pottery_null; - map_ulong_emplace_key(&dict, key, &kyle, pottery_null); - kyle->key = key; - kyle->value = value; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - bar_t *kyle = map_ulong_find(&dict, rand_get()); - if (kyle != NULL) - s += kyle->value; - } - g_result = s; - - map_ulong_destroy(&dict); -} - -/********************************************************************************************/ - -typedef struct { - char a[256]; -} char_array_t; -static inline void char_init (char_array_t *a) { a->a[0] = 0; } -static inline void char_set (char_array_t *a, const char_array_t b) { strcpy(a->a, b.a); } -static inline bool char_equal_p (const char_array_t a, const char_array_t b) { return strcmp(a.a,b.a)==0; } -static inline void char_clear (char_array_t *a) { (void)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; -} - -typedef struct bars_s { - char_array_t key; - char_array_t value; -} bars_t; - -#define POTTERY_OPEN_HASH_MAP_PREFIX map_achar - -#define POTTERY_OPEN_HASH_MAP_VALUE_TYPE bars_t -#define POTTERY_OPEN_HASH_MAP_KEY_TYPE char_array_t -#define POTTERY_OPEN_HASH_MAP_REF_KEY(v) v->key -#define POTTERY_OPEN_HASH_MAP_KEY_HASH(x) char_hash(&x) -#define POTTERY_OPEN_HASH_MAP_KEY_EQUAL(x, y) char_equal_p(x, y) -#define POTTERY_OPEN_HASH_MAP_LIFECYCLE_MOVE(p,q) memcpy(p, q, sizeof (bars_t)) - -#include "pottery/open_hash_map/pottery_open_hash_map_static.t.h" - -static void -test_dict_big(size_t n) -{ - map_achar_t dict; - map_achar_init(&dict); - - 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()); - bars_t * kyle = pottery_null; - map_achar_emplace_key(&dict, s1, &kyle, pottery_null); - char_set(&kyle->key, s1); - char_set(&kyle->value, 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()); - bars_t *kyle = map_achar_find(&dict, s1); - if (kyle != NULL) - s ++; - } - g_result = s; - - map_achar_destroy(&dict); -} - -/********************************************************************************************/ - -#define POTTERY_VECTOR_PREFIX vec_float -#define POTTERY_VECTOR_VALUE_TYPE float -#define POTTERY_VECTOR_LIFECYCLE_BY_VALUE 1 -#include "pottery/vector/pottery_vector_static.t.h" - -#define POTTERY_INTRO_SORT_PREFIX sort_float -#define POTTERY_INTRO_SORT_VALUE_TYPE float -#define POTTERY_INTRO_SORT_LIFECYCLE_MOVE_BY_VALUE 1 -#define POTTERY_INTRO_SORT_COMPARE_THREE_WAY(x, y) ( *x < *y ? -1 : *x > *y) -#include "pottery/intro_sort/pottery_intro_sort_static.t.h" - -static void test_sort(size_t n) -{ - vec_float_t a1; - vec_float_init(&a1); - - for(size_t i = 0; i < n; i++) { - vec_float_insert_last(&a1, rand_get() ); - } - sort_float(vec_float_at(&a1, 0), n); - g_result = *vec_float_at(&a1, 0); - vec_float_destroy(&a1); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 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}, - { 50, "Sort",10000000, 0, test_sort, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("POTTERY", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-qlibc.c b/bench/bench-qlibc.c deleted file mode 100644 index c5f73c3e..00000000 --- a/bench/bench-qlibc.c +++ /dev/null @@ -1,113 +0,0 @@ -#define NDEBUG -#define _GNU_SOURCE - -#include -#include -#include -#include -#include - -#include "qlibc/qlibc.h" - -#include "common.h" - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - qvector_t *a1 = qvector(16, sizeof(unsigned int), QVECTOR_RESIZE_DOUBLE); - if (!a1) abort(); - qvector_t *a2 = qvector(16, sizeof(unsigned int), QVECTOR_RESIZE_DOUBLE); - if (!a2) abort(); - - for(size_t i = 0; i < n; i++) { - unsigned int v = rand_get(); - bool success = a1->addlast(a1, &v); - if (!success) abort(); - v = rand_get(); - success = a2->addlast(a2, &v); - if (!success) abort(); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += *(unsigned int*)a1->getat(a1, i, false) * *(unsigned int *) a2->getat(a2, i, false); - } - g_result = s; - a1->free(a1); - a2->free(a2); -} - -/********************************************************************************************/ - -static void test_list (size_t n) -{ - qlist_t *a1 = qlist(0); - qlist_t *a2 = qlist(0); - - for(size_t i = 0; i < n; i++) { - unsigned int u = rand_get(), v = rand_get(); - a1->addlast(a1, &u, sizeof(unsigned int)); - a2->addlast(a2, &v, sizeof(unsigned int)); - } - unsigned int s = 0; - qlist_obj_t it1, it2; - memset(&it1, 0, sizeof (it1)); - memset(&it2, 0, sizeof (it2)); - while (a1->getnext(a1, &it1, false) == true - && a2->getnext(a2, &it2, false) == true) { - s += *(unsigned int*)it1.data * *(unsigned int*)it2.data; - } - g_result = s; - a1->free(a1); - a2->free(a2); -} - -/********************************************************************************************/ - -static int compare(const void *key1, size_t size1, - const void *key2, size_t size2) -{ - assert(size1 == sizeof(unsigned long)); - assert(size2 == sizeof(unsigned long)); - const unsigned long *pa = key1; - const unsigned long *pb = key2; - return (*pa < *pb) ? -1 : (*pa > *pb); -} - -static void test_rbtree(size_t n) -{ - qtreetbl_t *tree = qtreetbl(0); - tree->set_compare(tree, compare); - for (size_t i = 0; i < n; i++) { - unsigned long v = rand_get(); - tree->put_by_obj(tree, - &v, sizeof(unsigned long), /* key */ - &v, sizeof(unsigned long) /* value */ ); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long v = rand_get(); - void *obj = tree->get_by_obj(tree, (const char*)&v, sizeof(unsigned long), NULL, 0); - if (obj) - s += *(unsigned long*)obj; - } - g_result = s; - tree->free(tree); -} - -/* qlibc hash functions only accept a string as the key */ - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 20, "Array", 100000000, 0, test_array, 0}, - { 30, "Rbtree", 1000000, 0, test_rbtree, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("QLIBC", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-qt.cpp b/bench/bench-qt.cpp deleted file mode 100644 index cdeb3b9d..00000000 --- a/bench/bench-qt.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -static void test_list(size_t n) -{ - QLinkedList a1, a2; - for(size_t i = 0; i < n; i++) { - a1.push_back(rand_get() ); - a2.push_back(rand_get() ); - } - unsigned int s = 0; - for (QLinkedList::const_iterator ci1 = a1.begin(), ci2 = a2.begin (); ci1 != a1.end(); ++ci1, ++ci2) { - s += *ci1 * *ci2; - } - g_result = s; -} - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - QVector a1, a2; - for(size_t i = 0; i < n; i++) { - a1.push_back(rand_get() ); - a2.push_back(rand_get() ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += a1[i] * a2[i]; - } - g_result = s; -} - -/********************************************************************************************/ - -/* NOTE: QSet doesn't perform full ordering. I can't find any container - which is a set with total ordering within Qt. So we have to fake it. */ -static void test_rbtree(size_t n) -{ - QMap tree; - - for (size_t i = 0; i < n; i++) { - tree[rand_get()] = QHashDummyValue(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - QMap::iterator it = tree.find(rand_get()); - if (it != tree.end()) - s += it.key(); - } - g_result = s; -} - -/********************************************************************************************/ - -static void -test_dict1(size_t n) -{ - QMap dict; - - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - QMap::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it.value(); - } - g_result = s; -} - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - QHash dict; - - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - QHash::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it.value(); - } - g_result = s; -} - -/********************************************************************************************/ -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -uint qHash(const char_array_s &k) -{ - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; -}; - -static void -test_dict_big(size_t n) -{ - QHash dict; - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - QHash::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -static void test_sort(size_t n) -{ - QVector a1; - for(size_t i = 0; i < n; i++) { - a1.push_back(rand_get() ); - } - qSort(a1.begin(), a1.end()); - g_result = a1[0]; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 20, "Array", 100000000, 0, test_array, 0}, - { 30, "Rbtree", 1000000, 0, test_rbtree, 0}, - { 40, "dict(m)", 1000000, 0, test_dict1, 0}, - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict(u)", 1000000, 0, test_dict2, 0}, - { 50, "Sort",10000000, 0, test_sort, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("QT", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-rapidjson.cpp b/bench/bench-rapidjson.cpp deleted file mode 100644 index 08076641..00000000 --- a/bench/bench-rapidjson.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#define NDEBUG -#define RAPIDJSON_HAS_STDSTRING 1 - -#include "rapidjson/reader.h" -#include "rapidjson/document.h" -#include "rapidjson/prettywriter.h" -#include "rapidjson/filereadstream.h" -#include "rapidjson/filewritestream.h" -#include "rapidjson/encodedstream.h" -#include "rapidjson/error/en.h" - -#include -#include -#include - -#include "common.h" - -using namespace std; - -/********************************************************************************************/ - -vector vstring; -vector vstring2; - -static void -bench_vector_string_init(size_t n) -{ - for(size_t i = 0; i < n; i++) - { - char buff[100]; - snprintf(buff, sizeof(buff), "%zu", i); - std::string s(buff); - vstring.push_back(s); - } -} - -static void -bench_vector_string_init_big(size_t n) -{ - for(size_t i = 0; i < n; i++) - { - char buff[100]; - snprintf(buff, sizeof(buff), "%zu%zu%zu%zu%zu%zu", i, i, i, i, i, i); - std::string s(buff); - vstring.push_back(s); - } -} - -static void -bench_vector_string_json_run(size_t n) -{ - if (vstring.size() != n) { - printf("Size are different!\n"); - abort(); - } - - FILE *f = fopen("tmp-serial.json", "wt"); - if (!f) abort(); - { - // Prepare writer and output stream. - char writeBuffer[65536]; - typedef rapidjson::AutoUTFOutputStream OutputStream; - rapidjson::FileWriteStream os(f, writeBuffer, sizeof(writeBuffer)); - OutputStream eos(os, rapidjson::kUTF8, false); - rapidjson::PrettyWriter, rapidjson::AutoUTF > writer(eos); - - writer.StartArray(); - for(size_t i = 0; i < n; i++){ - writer.String(vstring[i]); - } - writer.EndArray(); - } - fclose(f); - - f = fopen("tmp-serial.json", "rt"); - if (!f) abort(); - { - char readBuffer[65536]; - rapidjson::FileReadStream is(f, readBuffer, sizeof(readBuffer)); - rapidjson::Document d; - d.ParseStream(is); - for(size_t i = 0; i < d.Size(); i++) { - rapidjson::Value& s = d[i]; - vstring2.push_back(s.GetString()); - } - } - fclose(f); - - if (vstring2.size() != n) { - printf("Size are different!\n"); - abort(); - } -} - -static void -bench_vector_string_clear(void) -{ - if (vstring != vstring2) { - printf("Array are different!\n"); - abort(); - } -} - -/********************************************************************************************/ - -vector vulong; -vector vulong2; - -static void -bench_vector_ulong_init(size_t n) -{ - for(size_t i = 0; i < n; i++) - { - vulong.push_back(i*i); - } -} - -static void -bench_vector_ulong_json_run(size_t n) -{ - if (vulong.size() != n) { - printf("Size are different!\n"); - abort(); - } - - FILE *f = fopen("tmp-serial.json", "wt"); - if (!f) abort(); - { - // Prepare writer and output stream. - char writeBuffer[65536]; - typedef rapidjson::AutoUTFOutputStream OutputStream; - rapidjson::FileWriteStream os(f, writeBuffer, sizeof(writeBuffer)); - OutputStream eos(os, rapidjson::kUTF8, false); - rapidjson::PrettyWriter, rapidjson::AutoUTF > writer(eos); - - writer.StartArray(); - for(size_t i = 0; i < n; i++){ - writer.Int64(vulong[i]); - } - writer.EndArray(); - } - fclose(f); - - f = fopen("tmp-serial.json", "rt"); - if (!f) abort(); - { - char readBuffer[65536]; - rapidjson::FileReadStream is(f, readBuffer, sizeof(readBuffer)); - rapidjson::Document d; - d.ParseStream(is); - for(size_t i = 0; i < d.Size(); i++) { - rapidjson::Value& s = d[i]; - vulong2.push_back(s.GetInt64()); - } - } - fclose(f); - - if (vulong2.size() != n) { - printf("Size are different!\n"); - abort(); - } -} - -static void -bench_vector_ulong_clear(void) -{ - if (vulong != vulong2) { - printf("Array are different!\n"); - abort(); - } -} - -/********************************************************************************************/ - -const config_func_t table[] = { - {110, "serial-json STR", 10000000, bench_vector_string_init, bench_vector_string_json_run, bench_vector_string_clear}, - {111, "serial-json STR.big", 10000000, bench_vector_string_init_big, bench_vector_string_json_run, bench_vector_string_clear}, - {112, "serial-json INT", 10000000, bench_vector_ulong_init, bench_vector_ulong_json_run, bench_vector_ulong_clear} -}; - -int main(int argc, const char *argv[]) -{ - test("RAPIDJSON", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-rigtorp-hashmap.cpp b/bench/bench-rigtorp-hashmap.cpp deleted file mode 100644 index 2d33d3c6..00000000 --- a/bench/bench-rigtorp-hashmap.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "rigtorp/HashMap.h" - -using namespace rigtorp; -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -// Hash for using unsigned long as lookup key -struct UL_Hash { - size_t operator()(const unsigned long v) { return v * 7; } -}; - -// Equal comparison for using unsigned long as lookup key -struct UL_Equal { - bool operator()(const unsigned long lhs, const unsigned long rhs) { - return lhs == rhs; - } -}; - -static void -test_dict2(size_t n) -{ - HashMap dict(16, -1UL); - - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - HashMap::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ - - -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -namespace std { - template <> struct hash { - std::size_t operator()(const char_array_s &k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; -} - -struct BIG_Hash { - size_t operator()(const char_array_s v) { return hash()(v); } -}; - -struct BIG_Equal { - bool operator()(const char_array_s lhs, const char_array_s rhs) { - return lhs == rhs; - } -}; - -static void -test_dict_big(size_t n) -{ - char_array_s empty; - HashMap dict(16, empty); - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - HashMap::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -struct STR_Hash { - size_t operator()(const string v) { return hash()(v); } -}; - -struct STR_Equal { - bool operator()(const string lhs, const string rhs) { - return lhs == rhs; - } -}; - - -static void -test_dict_str(size_t n) -{ - string empty; - HashMap dict(16, empty); - - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - string s2 = static_cast( &(ostringstream() << rand_get()) )->str(); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - HashMap::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict", 1000000, 0, test_dict2, 0}, - { 43, "DictStr", 1000000, 0, test_dict_str, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("RIGTORP-HASHMAP", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-rigtorp-mpmcqueue.cpp b/bench/bench-rigtorp-mpmcqueue.cpp deleted file mode 100644 index a4e25dbb..00000000 --- a/bench/bench-rigtorp-mpmcqueue.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include - -#include "common.h" - -/********************************************************************************************/ -rigtorp::MPMCQueue g_buff(4*64); -rigtorp::MPMCQueue g_final(4*64); - -static void final(void *arg) -{ - size_t *p_n = (size_t*) arg; - size_t n = *p_n; - unsigned long long j, s = 0; - for(unsigned int i = 0; i < n;i++) { - g_final.pop(j); - s += j; - } - g_result = s; -} - -static void conso(void *arg) -{ - unsigned int j; - size_t *p_n = (size_t*)arg; - size_t n = *p_n; - unsigned long long s = 0; - for(unsigned int i = 0; i < n;i++) { - g_buff.pop(j); - s += j; - } - g_final.push(s); -} - -static void prod(void *arg) -{ - size_t *p_n = (size_t*)arg; - size_t n = *p_n; - size_t r = n; - for(unsigned int i = 0; i < n;i++) { - g_buff.push(r); - r = r * 31421U + 6927U; - } -} - -static void test_queue(size_t n) -{ - const int cpu_count = get_cpu_count(); - const int prod_count = cpu_count/2; - const int conso_count = cpu_count - prod_count; - if (cpu_count < 2) { - fprintf(stderr, "WARNING: Can not measure Buffer performance.\n"); - return; - } - rand_get(); - // Create thread - m_thread_t idx_p[prod_count]; - m_thread_t idx_c[conso_count]; - m_thread_t idx_final; - for(int i = 0; i < prod_count; i++) { - m_thread_create (idx_p[i], prod, &n); - } - for(int i = 0; i < conso_count; i++) { - m_thread_create (idx_c[i], conso, &n); - } - size_t n2 = conso_count; - m_thread_create(idx_final, final, &n2); - - // Wait for jobs to be done. - for(int i = 0; i < prod_count; i++) { - m_thread_join(idx_p[i]); - } - for(int i = 0; i < conso_count; i++) { - m_thread_join(idx_c[i]); - } - m_thread_join(idx_final); - -} - - -/********************************************************************************************/ - -const config_func_t table[] = { - { 60, "Queue MPMC", 1000000, 0, test_queue, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("RIGTORP-MPMC-QUEUE", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-sparsepp.cpp b/bench/bench-sparsepp.cpp deleted file mode 100644 index fcec54fb..00000000 --- a/bench/bench-sparsepp.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -using spp::sparse_hash_map; -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - sparse_hash_map dict; - - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - sparse_hash_map::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ - -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -namespace std { - template <> struct hash { - std::size_t operator()(const char_array_s &k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; -} - -static void -test_dict_big(size_t n) -{ - sparse_hash_map dict; - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - sparse_hash_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -static void -test_dict_str(size_t n) -{ - sparse_hash_map dict; - - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - string s2 = static_cast( &(ostringstream() << rand_get()) )->str(); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = static_cast( &(ostringstream() << rand_get()) )->str(); - sparse_hash_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict", 1000000, 0, test_dict2, 0}, - { 43, "DictStr", 1000000, 0, test_dict_str, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("SPARSEPP", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-stc.c b/bench/bench-stc.c deleted file mode 100644 index da53ae8d..00000000 --- a/bench/bench-stc.c +++ /dev/null @@ -1,193 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "common.h" - -/********************************************************************************************/ - -#define i_val unsigned int -#define i_tag uint -#include - -static void test_array(size_t n) -{ - cvec_uint a1 = cvec_uint_init(), a2 = cvec_uint_init(); - - for(size_t i = 0; i < n; i++) { - cvec_uint_push_back(&a1, rand_get() ); - cvec_uint_push_back(&a2, rand_get() ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += *cvec_uint_at(&a1, i ) * *cvec_uint_at(&a2, i ); - } - g_result = s; - - cvec_uint_drop(&a1); - cvec_uint_drop(&a2); -} - -/********************************************************************************************/ -#define i_val unsigned int -#define i_tag uint -#include - -static void test_list(size_t n) -{ - clist_uint a1 = clist_uint_init(), a2 = clist_uint_init(); - - for(size_t i = 0; i < n; i++) { - clist_uint_push_front(&a1, rand_get() ); - clist_uint_push_front(&a2, rand_get() ); - } - unsigned int s = 0; - for(clist_uint_iter it1 = clist_uint_begin(&a1), it2 = clist_uint_begin(&a2) ; - it1.ref != clist_uint_end(&a1).ref ; - clist_uint_next(&it1), clist_uint_next(&it2) ) { - s += *it1.ref * *it2.ref; - } - g_result = s; - - clist_uint_drop(&a1); - clist_uint_drop(&a2); -} - -/********************************************************************************************/ - -#define i_tag ulong -#define i_key unsigned long -#include - -static void test_rbtree(size_t n) -{ - csset_ulong tree = csset_ulong_init(); - - for (size_t i = 0; i < n; i++) { - csset_ulong_insert(&tree, rand_get() ); - } - - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long j = rand_get(); - if (csset_ulong_get(&tree, j ) != NULL) - s+= j; - } - g_result = s; - csset_ulong_drop(&tree); -} - -/********************************************************************************************/ - -#define i_tag ulong -#define i_key unsigned long -#define i_val unsigned long -#include - -static void -test_dict(size_t n) -{ - cmap_ulong dict = cmap_ulong_init(); - - for (size_t i = 0; i < n; i++) { - unsigned long value = rand_get(); - unsigned long key = rand_get(); - cmap_ulong_insert_or_assign(&dict, key, value); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - const cmap_ulong_value*val = cmap_ulong_get(&dict, rand_get()); - if (val != NULL) - s += val->second; - } - g_result = s; - - cmap_ulong_drop(&dict); -} - -/********************************************************************************************/ - -typedef struct { - char a[256]; -} char_array_t; -static inline void char_init (char_array_t *a) { a->a[0] = 0; } -static inline void char_set (char_array_t *a, const char_array_t b) { strcpy(a->a, b.a); } -static inline bool char_equal_p (const char_array_t *a, const char_array_t *b) { return strcmp(a->a,b->a)==0; } -static inline void char_clear (char_array_t *a) { (void)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; -} - -#define i_tag achar -#define i_key char_array_t -#define i_val char_array_t -#define i_hash char_hash -#define i_eq char_equal_p -#include - -static void -test_dict_big(size_t n) -{ - cmap_achar dict = cmap_achar_init(); - - 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()); - cmap_achar_insert_or_assign(&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()); - const cmap_achar_value*val = cmap_achar_get(&dict, s1); - if (val != NULL) - s ++; - } - g_result = s; - - cmap_achar_drop(&dict); -} - -/********************************************************************************************/ - -#define i_val float -#define i_tag float -#include - -static void test_sort(size_t n) -{ - cvec_float a1 = cvec_float_init(); - - for(size_t i = 0; i < n; i++) { - cvec_float_push_back(&a1, rand_get() ); - } - cvec_float_sort(&a1); - g_result = *cvec_float_at(&a1, 0); - cvec_float_drop(&a1); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 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}, - { 50, "Sort",10000000, 0, test_sort, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("STC", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-stl.cpp b/bench/bench-stl.cpp deleted file mode 100644 index ab019d91..00000000 --- a/bench/bench-stl.cpp +++ /dev/null @@ -1,278 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace std; - -#include "common.h" - -/********************************************************************************************/ - -static void test_list(size_t n) -{ - list a1, a2; - for(size_t i = 0; i < n; i++) { - a1.push_back(rand_get() ); - a2.push_back(rand_get() ); - } - unsigned int s = 0; - for (list::const_iterator ci1 = a1.begin(), ci2 = a2.begin (); ci1 != a1.end(); ++ci1, ++ci2) { - s += *ci1 * *ci2; - } - g_result = s; -} - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - vector a1, a2; - for(size_t i = 0; i < n; i++) { - a1.push_back(rand_get() ); - a2.push_back(rand_get() ); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += a1[i] * a2[i]; - } - g_result = s; -} - -/********************************************************************************************/ - -static void test_deque(size_t n) -{ - deque a1, a2; - for(size_t i = 0; i < n; i++) { - a1.push_back(rand_get() ); - a2.push_back(rand_get() ); - } - unsigned int s = 0; - for(auto it1 = a1.cbegin(), it2 = a2.cbegin(); - it1 != a1.cend() ;it1++, it2++) { - s += *it1 * *it2; - } - g_result = s; -} - -/********************************************************************************************/ - -static void test_rbtree(size_t n) -{ - set tree; - - for (size_t i = 0; i < n; i++) { - tree.insert(rand_get()); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - set::iterator it = tree.find(rand_get()); - if (it != tree.end()) - s += *it; - } - g_result = s; -} - -/********************************************************************************************/ - -static void -test_dict1(size_t n) -{ - map dict; - - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - map::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ - -static void -test_dict2(size_t n) -{ - unordered_map dict; - - for (size_t i = 0; i < n; i++) { - dict[rand_get()] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unordered_map::iterator it = dict.find(rand_get()); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -static void -test_dict2_linear(size_t n) -{ - unordered_map dict; - - for (size_t i = 0; i < n; i++) { - dict[i] = rand_get(); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unordered_map::iterator it = dict.find(i); - if (it != dict.end()) - s += it->second; - } - g_result = s; -} - -/********************************************************************************************/ - -struct char_array_s { - char a[256]; - char_array_s () { a[0] = 0 ; } - char_array_s ( const char_array_s & other) { strcpy(a, other.a); } - bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; } -}; - -namespace std { - template <> struct hash { - std::size_t operator()(const char_array_s &k) const { - size_t hash = 0; - const char *s = k.a; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; - }; - }; -} - -static void -test_dict_big(size_t n) -{ - unordered_map dict; - - for (size_t i = 0; i < n; i++) { - char_array_s s1, s2; - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_s s1; - sprintf(s1.a, "%u", rand_get()); - unordered_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ -static void -test_dict_str(size_t n) -{ - unordered_map dict; - - for (size_t i = 0; i < n; i++) { - string s1 = to_string(rand_get()); - string s2 = to_string(rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = to_string (rand_get()); - unordered_map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -static void -test_dict_str2(size_t n) -{ - map dict; - - for (size_t i = 0; i < n; i++) { - string s1 = to_string(rand_get()); - string s2 = to_string(rand_get()); - dict[s1] = s2; - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - string s1 = to_string(rand_get()); - map::iterator it = dict.find(s1); - if (it != dict.end()) - s ++; - } - g_result = s; -} - -/********************************************************************************************/ - -static void test_sort(size_t n) -{ - vector a1; - for(size_t i = 0; i < n; i++) { - a1.push_back(rand_get() ); - } - sort(a1.begin(), a1.end()); - g_result = a1[0]; -} - -static void test_stable_sort(size_t n) -{ - vector a1; - for(size_t i = 0; i < n; i++) { - a1.push_back(rand_get() ); - } - stable_sort(a1.begin(), a1.end()); - g_result = a1[0]; -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 20, "Array", 100000000, 0, test_array, 0}, - { 21, "Deque", 100000000, 0, test_deque, 0}, - { 30, "Rbtree", 1000000, 0, test_rbtree, 0}, - { 40, "dict(m)", 1000000, 0, test_dict1, 0}, - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 42,"dict(u)", 1000000, 0, test_dict2, 0}, - { 43,"DictStr(u)", 1000000, 0, test_dict_str, 0}, - { 44,"DictStr(m)", 1000000, 0, test_dict_str2, 0}, - { 46, "dictLinear(u)", 1000000, 0, test_dict2_linear, 0}, - { 50, "Sort",10000000, 0, test_sort, 0}, - { 51, "Stable Sort",10000000, 0, test_stable_sort, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("STL", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-string-2.cpp b/bench/bench-string-2.cpp deleted file mode 100644 index c5bdeb3d..00000000 --- a/bench/bench-string-2.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * M*LIB - String Bench - * - * Copyright (c) 2017-2024, Patrick Pelissier - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * + Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * + Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define NDEBUG - -#include -#include -#include -#include - -#define M_USE_SMALL_NAME 0 -#include "common.h" - -#include "m-string.h" - -#ifdef BENCH_CAN_USE_SDS -extern "C" { -#include "sds.h" -}; -#endif - -#ifdef BENCH_CAN_USE_BSTRLIB -#include "bstrlib.h" -#include "bstrwrap.h" -#include "bstraux.h" -#endif - -#if defined(BENCH_CAN_USE_POTTERY) -#include "pottery/string/string.h" -#endif - -/* - * BENCH - * 2000000 - * 1. Generate N strings of random numbers 32 bits. - * 2. Concat all strings in a string usigned a random permutation of N. - * 3. Replace "1234" in the string into "WELL" until nothing remains. - * 4. Replace "56789" in the string into "DONE" until nothing remains. - * Return the final string length. - */ - -unsigned *permutation_tab = NULL; - -void random_permutation(unsigned n) -{ - if (permutation_tab) free(permutation_tab); - permutation_tab = (unsigned *) malloc(n * sizeof(unsigned)); - if (permutation_tab == NULL) abort(); - for(unsigned i = 0; i < n; i++) - permutation_tab[i] = i; - for(unsigned i = 0; i < n; i++) { - unsigned j = rand_get() % n; - unsigned k = rand_get() % n; - unsigned l = permutation_tab[j]; - permutation_tab[j] = permutation_tab[k]; - permutation_tab[k] = l; - } -} - -using namespace std; - -static void replace_all_stl(string &str, const char pattern[], const char replace[]) -{ - size_t pos = 0; - do { - pos = str.find(pattern, pos); - if (pos != string::npos) { - str.replace (pos, strlen(pattern), replace); - } - } while (pos != string::npos); -} - -size_t bench_stl(unsigned n) -{ - vector tab; - tab.resize(n); - for(unsigned i = 0; i < n; i++) - tab[i] = to_string(rand_get()); - - string str; - for(unsigned i = 0; i < n; i++) { - str += tab[permutation_tab[i]]; - } - - replace_all_stl(str, "1234", "WELL"); - replace_all_stl(str, "56789", "DONE"); - - return str.length(); -} - -size_t bench_mlib(unsigned n) -{ - m_string_t *tab = (m_string_t*) malloc (n * sizeof (m_string_t)); - assert (tab != 0); - // P1 - for(unsigned i = 0; i < n; i++) { - m_string_init(tab[i]); - m_string_set_ui(tab[i], rand_get()); - } - // P2 - m_string_t str; - m_string_init(str); - for(unsigned i = 0; i < n; i++) { - m_string_cat(str, tab[permutation_tab[i]]); - } - // P3 - m_string_replace_all_cstr(str, "1234", "WELL"); - m_string_replace_all_cstr(str, "56789", "DONE"); - size_t length = m_string_size(str); - - // Clean - m_string_clear(str); - for(unsigned i = 0; i < n; i++) { - m_string_clear(tab[i]); - } - free(tab); - return length; -} - - -#ifdef BENCH_CAN_USE_BSTRLIB - -static void replace_all_bstrlib(CBString &str, const char pattern[], const char replace[]) -{ - size_t pos = 0; - do { - pos = str.find(pattern, pos); - if (pos != string::npos) { - str.replace (pos, strlen(pattern), replace); - } - } while (pos != string::npos); -} - -size_t bench_bstrlib(unsigned n) -{ - vector tab; - tab.resize(n); - for(unsigned i = 0; i < n; i++) { - char tmp[10]; - sprintf(tmp, "%u", rand_get()); - tab[i] = tmp; - } - - CBString str; - for(unsigned i = 0; i < n; i++) { - str += tab[permutation_tab[i]]; - } - - replace_all_bstrlib(str, "1234", "WELL"); - replace_all_bstrlib(str, "56789", "DONE"); - - return str.length(); -} -#endif - -#ifdef BENCH_CAN_USE_SDS -sds SDS_replace_at(sds str, size_t pos, size_t len, const char str2[]) -{ - // simple implementation as replace is not available - sds a = sdsnewlen((const void*) str, pos); - a = sdscat(a, str2); - a = sdscat(a, &str[pos+len]); - sdsfree(str); - return a; -} - -sds replace_all_sds(sds str, const char pattern[], const char replace[]) -{ - size_t pos = 0; - do { - char *p = strstr(&str[pos], pattern); - pos = p == NULL ? -1U : (p - str); - if (pos != -1U) { - str = SDS_replace_at(str, pos, strlen(pattern), replace); - } - } while (pos != -1U); - return str; -} - -size_t bench_sds(unsigned n) -{ - sds *tab = (sds*) malloc (n * sizeof (sds)); - assert (tab != 0); - // P1 - for(unsigned i = 0; i < n; i++) { - tab[i] = sdsfromlonglong(rand_get()); - } - // P2 - sds str = sdsempty(); - for(unsigned i = 0; i < n; i++) { - str = sdscat(str, tab[permutation_tab[i]]); - } - // P3 - str = replace_all_sds(str, "1234", "WELL"); - str = replace_all_sds(str, "56789", "DONE"); - // Clean - size_t length = sdslen(str); - sdsfree(str); - for(unsigned i = 0; i < n; i++) { - sdsfree(tab[i]); - } - free(tab); - return length; -} -#endif - -#if defined(BENCH_CAN_USE_POTTERY) - -size_t pottery_find_cstr(string_t *b, size_t index, const char *pattern) -{ - // I cannot find such function in the API - const char *s = string_cstr(b); - const char *r = strstr(&s[index], pattern); - return r == NULL ? SIZE_MAX : r - s; -} - -void pottery_replace_all_str(string_t *str, const char *s, const char *d) -{ - size_t i = 0; - while (true) { - i = pottery_find_cstr(str, i, s); - if (i==SIZE_MAX) return; - string_remove(str, i, strlen(s)); - string_insert_cstr(str, i, d); - } -} - -size_t bench_pottery(unsigned n) -{ - string_t *tab = (string_t*) malloc (n * sizeof (string_t)); - assert (tab != 0); - // P1 - for(unsigned i = 0; i < n; i++) { - string_init(&tab[i]); - string_append_format(&tab[i], "%u", rand_get()); - } - // P2 - string_t str; - string_init(&str); - for(unsigned i = 0; i < n; i++) { - string_append_string(&str, &tab[permutation_tab[i]]); - } - // P3 - - pottery_replace_all_str(&str, "1234", "WELL"); - pottery_replace_all_str(&str, "56789", "DONE"); - size_t length = string_length(&str); - - // Clean - string_clear(&str); - for(unsigned i = 0; i < n; i++) { - string_clear(&tab[i]); - } - free(tab); - return length; -} -#endif - -int main(int argc, const char *argv[]) -{ - unsigned length, n = atoi(argv[1]); - unsigned select = atoi(argv[2]); - const char *name; - random_permutation(n); - rand_init(); - unsigned long long t0 = cputime(); - - switch (select) { - case 0: - length = bench_mlib(n); - name = "MLIB"; - break; - case 1: - length = bench_stl(n); - name = "STL"; - break; -#ifdef BENCH_CAN_USE_SDS - case 2: - length = bench_sds(n); - name = "SDS"; - break; -#endif -#ifdef BENCH_CAN_USE_BSTRLIB - case 4: - length = bench_bstrlib(n); - name = "BSTRLIB"; - break; -#endif -#if defined(BENCH_CAN_USE_POTTERY) - case 5: - length = bench_pottery(n); - name = "POTTERY"; - break; -#endif - default: - exit(0); - } - unsigned long long t1 = cputime(); - printf("%5.5s LENGTH=%u T= %f s\n", name, length, (t1-t0) / 1000000.0 ); - - return 0; -} diff --git a/bench/bench-string.cpp b/bench/bench-string.cpp deleted file mode 100644 index bdd603f4..00000000 --- a/bench/bench-string.cpp +++ /dev/null @@ -1,1173 +0,0 @@ -/* - * This source file is part of the bstring string library as cppbench.cpp - * The bstring string library is written by Paul Hsieh in 2002-2015, - * and is covered by the BSD open source license. See : - * * https://github.com/websnarf/bstrlib - * * http://bstring.sourceforge.net/ - * * http://prdownloads.sourceforge.net/bstring/examples-09282006.zip?download - - Copyright (c) 2014, Paul Hsieh - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of bstrlib nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Update of integrating M*LIB, LIBSRT, SDS, GLIB & POTTERY - Copyright (c) 2018-2024 Patrick Pelissier - */ - -/* - * Benchmark based on the features tested by benchmark seen here: - * http://www.utilitycode.com/str/performance.aspx - * - * The idea is to measure the performance empty constructors, char * - * constructors, assignment, concatenation and scanning. - * - */ - -#define NDEBUG - -#include -#include -#include - -#define M_USE_SMALL_NAME 0 -#include "common.h" - -#ifdef BENCH_CAN_USE_MSTARLIB -#include "m-string.h" -#endif - -#ifdef BENCH_CAN_USE_BSTRLIB -#include "bstrlib.h" -#include "bstrwrap.h" -#include "bstraux.h" -#endif - -#ifdef BENCH_CAN_USE_LIBSRT -#include "sstring.h" -#endif - -#ifdef BENCH_CAN_USE_SDS -extern "C" { -#include "sds.h" -}; -#endif - -#if defined (BENCH_CAN_USE_STL) -#include -#endif - -#if defined(BENCH_CAN_USE_GLIB) -#include "gmodule.h" -#endif - -#if defined(BENCH_CAN_USE_POTTERY) -#include "pottery/string/string.h" -#endif - -/* Time of a test */ -#define TEST_SECONDS (5) - -/* - * This macro puts a memory barrier and prevents the optimizer from - * optimizing too much the inline functions and literraly breaking - * the benchmark by doing nothing. - * Better than nothing, but far from perfect. - */ -#define BARRIER(addr) compiler_barrier((void*) addr) - -bool print_csv = false; - -int timeTest (double &res, int (*testfn) (int count), int count) { - clock_t t0, t1; - int p = 0; - double x, c = 0; - - t0 = clock (); - - do { - p += testfn (count); - t1 = clock (); - - c += count; - if (t1 == t0) { - if (count < (INT_MAX / 2)) count += count; - continue; - } - - if (t1 - t0 >= TEST_SECONDS*CLOCKS_PER_SEC) break; - - x = (TEST_SECONDS*CLOCKS_PER_SEC - (t1 - t0)) * c / (t1 - t0); - - if (x > INT_MAX) x = INT_MAX; - count = (int) x; - if (count < 1000) count = 1000; - - } while (1); - - res = c * CLOCKS_PER_SEC / (t1 - t0); - return p; -} - -#define SMALLTESTSTRING1 ("hello") - -#define TESTSTRING1 ("") - -#if defined (BENCH_CAN_USE_STL) -int testSTL_emptyCtor (int count) { - int i, c = 0; - for (i=0; i < count; i++) { - std::string b; - BARRIER(&b); - c += b.length () ^ i; - } - return c; -} - -int testSTL_nonemptyCtor (int count) { - int i, c = 0; - for (i=0; i < count; i++) { - std::string b (TESTSTRING1); - BARRIER(&b); - c += b.length () ^ i; - } - return c; -} - -int testSTL_smallnonemptyCtor (int count) { - int i, c = 0; - for (i=0; i < count; i++) { - std::string b (SMALLTESTSTRING1); - BARRIER(&b); - c += b.length () ^ i; - } - return c; -} - -int testSTL_cstrAssignment (int count) { - int i, c = 0; - std::string b; - - for (i=0; i < count; i++) { - b = TESTSTRING1; - BARRIER(&b); - c += b.length () ^ i; - } - return c; -} - -int testSTL_extraction (int count) { - int i, c = 0; - std::string b (TESTSTRING1); - - for (i=0; i < count; i++) { - c += b[(i & 7)]; - c += b[(i & 7) ^ 8]; - c += b.c_str()[(i & 7) ^ 4] ^ i; - BARRIER(&b); - } - return c; -} - -int testSTL_scan (int count) { -int i, c = 0; - std::string b ("Dot. 123. Some more data."); - - for (i=0; i < count; i++) { - c += b.find ('.'); - c += b.find ("123"); - c += b.find_first_of ("sm") ^i; - BARRIER(&b); - } - return c; -} - -int testSTL_concat (int count) { - int i, j, c = 0; - std::string a (TESTSTRING1); - std::string accum; - - for (j=0; j < count; j++) { - accum = ""; - for (i=0; i < 250; i++) { - accum += a; - accum += "!!"; - BARRIER(&accum); - c += accum.length() ^i; - } - } - return c; -} - -int testSTL_replace (int count) { - int j, c = 0; - std::string a (TESTSTRING1); - - for (j=0; j < count; j++) { - a.replace (11, 4, "XXXXXX"); - a.replace (23, 2, "XXXXXX"); - a.replace ( 4, 8, "XX"); - BARRIER(&a); - c += a.length () ^ j; - } - return c; -} - -#endif - -#ifdef BENCH_CAN_USE_BSTRLIB -int testCBS_emptyCtor (int count) { - int i, c = 0; - for (i=0; i < count; i++) { - CBString b; - BARRIER(&b); - c += b.length ()^i; - } - return c; -} - -int testCBS_nonemptyCtor (int count) { - int i, c = 0; - for (i=0; i < count; i++) { - CBString b (TESTSTRING1); - BARRIER(&b); - c += b.length () ^i; - } - return c; -} - -int testCBS_smallnonemptyCtor (int count) { - int i, c = 0; - for (i=0; i < count; i++) { - CBString b (SMALLTESTSTRING1); - BARRIER(&b); - c += b.length () ^i; - } - return c; -} - -int testCBS_cstrAssignment (int count) { - int i, c = 0; - CBString b; - - for (i=0; i < count; i++) { - b = TESTSTRING1; - BARRIER(&b); - c += b.length () ^i; - } - return c; -} - -int testCBS_extraction (int count) { - int i, c = 0; - CBString b (TESTSTRING1); - - for (i=0; i < count; i++) { - c += b[(i & 7)]; - c += b[(i & 7) ^ 8]; - c += ((const char *)b)[(i & 7) ^ 4] ^i; - BARRIER(&b); - } - return c; -} - -int testCBS_scan (int count) { - int i, c = 0; - CBString b ("Dot. 123. Some more data."); - - for (c=i=0; i < count; i++) { - c += b.find ('.'); - c += b.find ("123"); - c += b.findchr ("sm") ^i; - BARRIER(&b); - } - return c; -} - -int testCBS_concat (int count) { - int i, j, c = 0; - CBString a (TESTSTRING1); - CBString accum; - - for (j=0; j < count; j++) { - accum = ""; - for (i=0; i < 250; i++) { - accum += a; - accum += "!!"; - BARRIER(&accum); - c+= accum.length() ^i; - } - } - return c; -} - -int testCBS_replace (int count) { - int j, c = 0; - CBString a (TESTSTRING1); - - for (j=0; j < count; j++) { - a.replace (11, 4, "XXXXXX"); - a.replace (23, 2, "XXXXXX"); - a.replace ( 4, 8, "XX"); - BARRIER(&a); - c += a.length () ^j; - } - return c; -} -#endif - -#ifdef BENCH_CAN_USE_LIBSRT -int testSRT_emptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - srt_string *b = ss_alloc(0); - BARRIER(b); - c += ss_size(b) ^i; - ss_free(&b); - } - return c; -} - -int testSRT_nonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - srt_string *b = ss_dup_c(TESTSTRING1); - BARRIER(b); - c += ss_size(b) ^i; - ss_free(&b); - } - return c; -} - -int testSRT_smallnonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - srt_string *b = ss_dup_c(SMALLTESTSTRING1); - BARRIER(b); - c += ss_size(b) ^i; - ss_free(&b); - } - return c; -} - -int testSRT_cstrAssignment (int count) { - int i, c = 0; - srt_string *b = ss_alloc(0); - for (c=i=0; i < count; i++) { - ss_cpy_cn(&b, TESTSTRING1, strlen(TESTSTRING1)); - BARRIER(b); - c += ss_size(b) ^i; - } - ss_free(&b); - return c; -} - -int testSRT_extraction (int count) { - int i, c = 0; - srt_string *b = ss_dup_c(TESTSTRING1); - for (c=i=0; i < count; i++) { - c += ss_at(b,(i & 7)); - c += ss_at(b,(i & 7) ^ 8); - c += ss_at(b,(i & 7) ^ 4) ^i; - BARRIER(b); - } - ss_free(&b); - return c; -} - -int testSRT_scan (int count) { - int i, c = 0; - srt_string *b = ss_dup_c("Dot. 123. Some more data."); - for (c=i=0; i < count; i++) { - c += ss_findc (b, 0, '.'); - c += ss_find_cn (b, 0, "123", strlen("123")); - //c += ss_pbrk (b, 0, "sm") ^i; - c += ss_findb (b, 0) ^i; - BARRIER(b); - } - ss_free(&b); - return c; -} - - -int testSRT_concat (int count) { - int i, j, c = 0; - srt_string *a = ss_dup_c(TESTSTRING1); - srt_string *accum = ss_alloc(0); - - for (j=0; j < count; j++) { - ss_cpy_c(&accum, ""); - for (i=0; i < 250; i++) { - ss_cat(&accum, a, NULL); - ss_cat_c(&accum, "!!", NULL); - BARRIER(accum); - c += ss_size(accum) ^i; - } - } - ss_free(&a); - ss_free(&accum); - return c; -} - -#endif - -#ifdef BENCH_CAN_USE_MSTARLIB -int testMLIB_emptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - m_string_t b; - m_string_init(b); - BARRIER(&b); - c += m_string_size(b) ^i; - m_string_clear(b); - } - return c; -} - -int testMLIB_nonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - m_string_t b; - m_string_init_set_cstr(b, TESTSTRING1); - BARRIER(&b); - c += m_string_size(b) ^i; - m_string_clear(b); - } - return c; -} - -int testMLIB_smallnonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - m_string_t b; - m_string_init_set_cstr(b, SMALLTESTSTRING1); - BARRIER(&b); - c += m_string_size(b) ^i; - m_string_clear(b); - } - return c; -} - -int testMLIB_cstrAssignment (int count) { - int i, c = 0; - m_string_t b; - m_string_init(b); - for (c=i=0; i < count; i++) { - m_string_set_cstr(b, TESTSTRING1); - BARRIER(&b); - c += m_string_size(b) ^i; - } - m_string_clear(b); - return c; -} - -int testMLIB_extraction (int count) { - int i, c = 0; - - m_string_t b; - m_string_init_set_cstr(b, TESTSTRING1); - - for (c=i=0; i < count; i++) { - c += m_string_get_char(b, (i & 7)); - c += m_string_get_char(b, (i & 7) ^ 8); - c += m_string_get_char(b, (i & 7) ^ 4) ^i; - BARRIER(&b); - } - m_string_clear(b); - return c; -} - -int testMLIB_scan (int count) { - int i, c = 0; - m_string_t b; - m_string_init_set_cstr(b, "Dot. 123. Some more data."); - - for (c=i=0; i < count; i++) { - c += m_string_search_char (b, '.'); - c += m_string_search_cstr (b, "123"); - c += m_string_search_pbrk (b, "sm") ^i; - BARRIER(&b); - } - m_string_clear(b); - return c; -} - -int testMLIB_concat (int count) { - int i, j, c = 0; - m_string_t a, accum; - m_string_init_set_cstr(a, TESTSTRING1); - m_string_init (accum); - - for (j=0; j < count; j++) { - m_string_set_cstr(accum, ""); - for (i=0; i < 250; i++) { - m_string_cat(accum, a); - m_string_cat_cstr(accum, "!!"); - BARRIER(&accum); - c += m_string_size(accum) ^i; - } - } - m_string_clear(a); - m_string_clear(accum); - return c; -} - -int testMLIB_replace (int count) { - int j, c = 0; - m_string_t a; - m_string_init_set_cstr(a, TESTSTRING1); - - for (j=0; j < count; j++) { - m_string_replace_at(a, 11, 4, "XXXXXX"); - m_string_replace_at(a, 23, 2, "XXXXXX"); - m_string_replace_at(a, 4, 8, "XX"); - BARRIER(&a); - c += m_string_size(a) ^j; - } - - m_string_clear(a); - return c; -} -#endif - -#ifdef BENCH_CAN_USE_SDS -int testSDS_emptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - sds b; - b = sdsempty(); - BARRIER(b); - c += sdslen(b) ^ i; - sdsfree(b); - } - return c; -} - -int testSDS_nonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - sds b; - b = sdsnew(TESTSTRING1); - BARRIER(b); - c += sdslen(b) ^i; - sdsfree(b); - } - return c; -} - -int testSDS_smallnonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - sds b; - b = sdsnew(SMALLTESTSTRING1); - BARRIER(b); - c += sdslen(b) ^i; - sdsfree(b); - } - return c; -} - -int testSDS_cstrAssignment (int count) { - int i, c = 0; - sds b; - b = sdsempty(); - for (c=i=0; i < count; i++) { - b = sdscpy(b, TESTSTRING1); - BARRIER(b); - c += sdslen(b) ^i; - } - sdsfree(b); - return c; -} - -int testSDS_extraction (int count) { - int i, c = 0; - - sds b; - b = sdsnew(TESTSTRING1); - - for (c=i=0; i < count; i++) { - c += b[(i & 7)]; - c += b[(i & 7) ^ 8]; - c += b[(i & 7) ^ 4] ^i; - BARRIER(b); - } - sdsfree(b); - return c; -} - -int testSDS_scan (int count) { - int i, c = 0; - sds b; - b = sdsnew("Dot. 123. Some more data."); - - for (c=i=0; i < count; i++) { - c += (intptr_t) strchr(b, '.'); - c += (intptr_t) strstr (b, "123"); - c += (intptr_t) strpbrk (b, "sm") ^i; - BARRIER(b); - } - sdsfree(b); - return c; -} - - -int testSDS_concat (int count) { - int i, j, c = 0; - sds a, accum; - a = sdsnew(TESTSTRING1); - accum = sdsempty(); - - for (j=0; j < count; j++) { - accum = sdscpy(accum, ""); - for (i=0; i < 250; i++) { - accum = sdscat(accum, a); - accum = sdscat(accum, "!!"); - BARRIER(accum); - c += sdslen(accum) ^i; - } - } - sdsfree(a); - sdsfree(accum); - return c; -} - -sds SDS_replace_at(sds str, size_t pos, size_t len, const char str2[]) -{ - // simple implementation as replace is not available - sds a = sdsnewlen((const void*) str, pos); - a = sdscat(a, str2); - a = sdscat(a, &str[pos+len]); - sdsfree(str); - return a; -} - -int testSDS_replace (int count) { - int j, c = 0; - sds a; - a = sdsnew(TESTSTRING1); - for (j=0; j < count; j++) { - a = SDS_replace_at(a, 11, 4, "XXXXXX"); - a = SDS_replace_at(a, 23, 2, "XXXXXX"); - a = SDS_replace_at(a, 4, 8, "XX"); - BARRIER(&a); - c += sdslen(a) ^j; - } - sdsfree(a); - return c; -} - -#endif - - -#ifdef BENCH_CAN_USE_GLIB -int testGLIB_emptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - GString *b = g_string_new(""); - BARRIER(b); - c += b->len; - g_string_free(b, TRUE); - } - return c; -} - -int testGLIB_nonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - GString *b = g_string_new(TESTSTRING1); - BARRIER(b); - c += b->len; - g_string_free(b, TRUE); - } - return c; -} - -int testGLIB_smallnonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - GString *b = g_string_new(SMALLTESTSTRING1); - BARRIER(b); - c += b->len; - g_string_free(b, TRUE); - } - return c; -} - -int testGLIB_cstrAssignment (int count) { - int i, c = 0; - GString *b = g_string_new(""); - for (c=i=0; i < count; i++) { - b = g_string_assign(b, TESTSTRING1); - BARRIER(b); - c += b->len ^i; - } - g_string_free(b, TRUE); - return c; -} - -int testGLIB_extraction (int count) { - int i, c = 0; - GString *b = g_string_new(TESTSTRING1); - for (c=i=0; i < count; i++) { - c += b->str[(i & 7)]; - c += b->str[(i & 7) ^ 8]; - c += b->str[(i & 7) ^ 4] ^i; - BARRIER(b); - } - g_string_free(b, TRUE); - return c; -} - -int testGLIB_scan (int count) { - int i, c = 0; - GString *b = g_string_new("Dot. 123. Some more data."); - - for (c=i=0; i < count; i++) { - c += (strchr(b->str, '.')-b->str); - c += (strstr (b->str, "123")-b->str); - c += (strpbrk (b->str, "sm")-b->str) ^i; - BARRIER(b); - } - g_string_free(b, TRUE); - return c; -} - - -int testGLIB_concat (int count) { - int i, j, c = 0; - GString *a = g_string_new(TESTSTRING1); - GString *accum = g_string_new(""); - - for (j=0; j < count; j++) { - accum = g_string_assign(accum, ""); - for (i=0; i < 250; i++) { - accum = g_string_append(accum, a->str); - accum = g_string_append(accum, "!!"); - BARRIER(accum); - c += accum->len ^i; - } - } - g_string_free(a, TRUE); - g_string_free(accum, TRUE); - return c; -} - -//int testGLIB_replace (int count): not available -#endif - -#ifdef BENCH_CAN_USE_POTTERY -int testPOTTERY_emptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - string_t b; - string_init(&b); - BARRIER(&b); - c += string_length(&b) ^i; - string_clear(&b); - } - return c; -} - -int testPOTTERY_nonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - string_t b; - string_init_cstr(&b, TESTSTRING1); - BARRIER(&b); - c += string_length(&b) ^i; - string_clear(&b); - } - return c; -} - -int testPOTTERY_smallnonemptyCtor (int count) { - int i, c = 0; - for (c=i=0; i < count; i++) { - string_t b; - string_init_cstr(&b, SMALLTESTSTRING1); - BARRIER(&b); - c += string_length(&b) ^i; - string_clear(&b); - } - return c; -} - -int testPOTTERY_cstrAssignment (int count) { - int i, c = 0; - string_t b; - string_init(&b); - for (c=i=0; i < count; i++) { - string_set_cstr(&b, TESTSTRING1); - BARRIER(&b); - c += string_length(&b) ^i; - } - string_clear(&b); - return c; -} - -int testPOTTERY_extraction (int count) { - int i, c = 0; - - string_t b; - string_init_cstr(&b, TESTSTRING1); - - for (c=i=0; i < count; i++) { - c += string_cstr(&b)[(i & 7)]; - c += string_cstr(&b)[(i & 7) ^ 8]; - c += string_cstr(&b)[(i & 7) ^ 4] ^i; - BARRIER(&b); - } - string_clear(&b); - return c; -} - -size_t pottery_find_cstr(string_t *b, const char *pattern) -{ - // I cannot find such function in the API - const char *s = string_cstr(b); - const char *r = strstr(s, pattern); - return r == NULL ? SIZE_MAX : r - s; -} - -int testPOTTERY_scan (int count) { - int i, c = 0; - string_t b; - string_init_cstr(&b, "Dot. 123. Some more data."); - - for (c=i=0; i < count; i++) { - c += string_find_char (&b, 0, '.'); - c += pottery_find_cstr (&b, "123"); - c += string_find_chars_cstr (&b, 0, "sm") ^i; - BARRIER(&b); - } - string_clear(&b); - return c; -} - -int testPOTTERY_concat (int count) { - int i, j, c = 0; - string_t a, accum; - string_init_cstr(&a, TESTSTRING1); - string_init (&accum); - - for (j=0; j < count; j++) { - string_set_cstr(&accum, ""); - for (i=0; i < 250; i++) { - string_append_string(&accum, &a); - string_append_cstr(&accum, "!!"); - BARRIER(&accum); - c += string_length(&accum) ^i; - } - } - string_clear(&a); - string_clear(&accum); - return c; -} - -// No replace function available -#endif - - -#define NTESTS 8 -struct flags { - int runtest[NTESTS]; -}; - -static void -print(const char library[], const char function[], double cps) -{ - if (print_csv == false) - { - printf ("%16s %30s : %20.1f per second\n", library, function, cps); - } - else - { - printf ("\"%s\";\"%s\";%f\n", library, function, cps); - } -} - -int benchTest (const struct flags * runflags) { - int c = 0; - double cps; - -#if defined (BENCH_CAN_USE_STL) - if (runflags->runtest[0]) { - c += timeTest (cps, testSTL_emptyCtor, 100000); - print ("std::string", "empty constructor", cps); - } - if (runflags->runtest[1]) { - c += timeTest (cps, testSTL_nonemptyCtor, 100000); - print ("std::string", "non-empty constructor", cps); - } - if (runflags->runtest[2]) { - c += timeTest (cps, testSTL_smallnonemptyCtor, 100000); - print ("std::string", "small non-empty constructor", cps); - } - if (runflags->runtest[3]) { - c += timeTest (cps, testSTL_cstrAssignment, 100000); - print ("std::string", "char * assignment", cps); - } - if (runflags->runtest[4]) { - c += timeTest (cps, testSTL_extraction, 100000); - print ("std::string", "char extraction", cps); - } - if (runflags->runtest[5]) { - c += timeTest (cps, testSTL_scan, 100000); - print ("std::string", "scan", cps); - } - if (runflags->runtest[6]) { - c += timeTest (cps, testSTL_concat, 10); - print ("std::string", "concatenation", cps * 250); - } - if (runflags->runtest[7]) { - c += timeTest (cps, testSTL_replace, 10000); - print ("std::string", "replace", cps); - } -#endif - -#ifdef BENCH_CAN_USE_BSTRLIB - if (runflags->runtest[0]) { - c += timeTest (cps, testCBS_emptyCtor, 100000); - print ("CBString", "empty constructor", cps); - } - if (runflags->runtest[1]) { - c += timeTest (cps, testCBS_nonemptyCtor, 100000); - print ("CBString", "non-empty constructor", cps); - } - if (runflags->runtest[2]) { - c += timeTest (cps, testCBS_smallnonemptyCtor, 100000); - print ("CBString", "small non-empty constructor", cps); - } - if (runflags->runtest[3]) { - c += timeTest (cps, testCBS_cstrAssignment, 100000); - print ("CBString", "char * assignment", cps); - } - if (runflags->runtest[4]) { - c += timeTest (cps, testCBS_extraction, 100000); - print ("CBString", "char extraction", cps); - } - if (runflags->runtest[5]) { - c += timeTest (cps, testCBS_scan, 100000); - print ("CBString", "scan", cps); - } - if (runflags->runtest[6]) { - c += timeTest (cps, testCBS_concat, 10); - print ("CBString", "concatenation", cps * 250); - } - if (runflags->runtest[7]) { - c += timeTest (cps, testCBS_replace, 10000); - print ("CBString", "replace", cps); - } -#endif - -#ifdef BENCH_CAN_USE_LIBSRT - if (runflags->runtest[0]) { - c += timeTest (cps, testSRT_emptyCtor, 100000); - print ("LIBSRT", "empty constructor", cps); - } - if (runflags->runtest[1]) { - c += timeTest (cps, testSRT_nonemptyCtor, 100000); - print ("LIBSRT", "non-empty constructor", cps); - } - if (runflags->runtest[2]) { - c += timeTest (cps, testSRT_smallnonemptyCtor, 100000); - print ("LIBSRT", "small non-empty constructor", cps); - } - if (runflags->runtest[3]) { - c += timeTest (cps, testSRT_cstrAssignment, 100000); - print ("LIBSRT", "char * assignment", cps); - } - if (runflags->runtest[4]) { - c += timeTest (cps, testSRT_extraction, 100000); - print ("LIBSRT", "char extraction", cps); - } - if (runflags->runtest[5]) { - c += timeTest (cps, testSRT_scan, 100000); - print ("LIBSRT", "scan", cps); - } - if (runflags->runtest[6]) { - c += timeTest (cps, testSRT_concat, 10); - print ("LIBSRT", "concatenation", cps * 250); - } -#endif - -#ifdef BENCH_CAN_USE_MSTARLIB - if (runflags->runtest[0]) { - c += timeTest (cps, testMLIB_emptyCtor, 100000); - print ("M*LIB", "empty constructor", cps); - } - if (runflags->runtest[1]) { - c += timeTest (cps, testMLIB_nonemptyCtor, 100000); - print ("M*LIB", "non-empty constructor", cps); - } - if (runflags->runtest[2]) { - c += timeTest (cps, testMLIB_smallnonemptyCtor, 100000); - print ("M*LIB", "small non-empty constructor", cps); - } - if (runflags->runtest[3]) { - c += timeTest (cps, testMLIB_cstrAssignment, 100000); - print ("M*LIB", "Char * assignment", cps); - } - if (runflags->runtest[4]) { - c += timeTest (cps, testMLIB_extraction, 100000); - print ("M*LIB", "char extraction", cps); - } - if (runflags->runtest[5]) { - c += timeTest (cps, testMLIB_scan, 100000); - print ("M*LIB", "scan", cps); - } - if (runflags->runtest[6]) { - c += timeTest (cps, testMLIB_concat, 10); - print ("M*LIB", "concatenation", cps * 250); - } - if (runflags->runtest[7]) { - c += timeTest (cps, testMLIB_replace, 10000); - print ("M*LIB", "replace", cps); - } -#endif - -#ifdef BENCH_CAN_USE_SDS - if (runflags->runtest[0]) { - c += timeTest (cps, testSDS_emptyCtor, 100000); - print ("SDS", "empty constructor", cps); - } - if (runflags->runtest[1]) { - c += timeTest (cps, testSDS_nonemptyCtor, 100000); - print ("SDS", "non-empty constructor", cps); - } - if (runflags->runtest[2]) { - c += timeTest (cps, testSDS_smallnonemptyCtor, 100000); - print ("SDS", "small non-empty constructor", cps); - } - if (runflags->runtest[3]) { - c += timeTest (cps, testSDS_cstrAssignment, 100000); - print ("SDS", "char * assignment", cps); - } - if (runflags->runtest[4]) { - c += timeTest (cps, testSDS_extraction, 100000); - print ("SDS", "char extraction", cps); - } - if (runflags->runtest[5]) { - c += timeTest (cps, testSDS_scan, 100000); - print ("SDS", "scan", cps); - } - if (runflags->runtest[6]) { - c += timeTest (cps, testSDS_concat, 10); - print ("SDS", "concatenation", cps * 250); - } - if (runflags->runtest[7]) { - c += timeTest (cps, testSDS_replace, 10); - print ("SDS", "replace", cps); - } -#endif - -#ifdef BENCH_CAN_USE_GLIB - if (runflags->runtest[0]) { - c += timeTest (cps, testGLIB_emptyCtor, 100000); - print ("GLIB", "empty constructor", cps); - } - if (runflags->runtest[1]) { - c += timeTest (cps, testGLIB_nonemptyCtor, 100000); - print ("GLIB", "non-empty constructor", cps); - } - if (runflags->runtest[2]) { - c += timeTest (cps, testGLIB_smallnonemptyCtor, 100000); - print ("GLIB", "small non-empty constructor", cps); - } - if (runflags->runtest[3]) { - c += timeTest (cps, testGLIB_cstrAssignment, 100000); - print ("GLIB", "Char * assignment", cps); - } - if (runflags->runtest[4]) { - c += timeTest (cps, testGLIB_extraction, 100000); - print ("GLIB", "char extraction", cps); - } - if (runflags->runtest[5]) { - c += timeTest (cps, testGLIB_scan, 100000); - print ("GLIB", "scan", cps); - } - if (runflags->runtest[6]) { - c += timeTest (cps, testGLIB_concat, 10); - print ("GLIB", "concatenation", cps * 250); - } -#endif - -#ifdef BENCH_CAN_USE_POTTERY - if (runflags->runtest[0]) { - c += timeTest (cps, testPOTTERY_emptyCtor, 100000); - print ("POTTERY", "empty constructor", cps); - } - if (runflags->runtest[1]) { - c += timeTest (cps, testPOTTERY_nonemptyCtor, 100000); - print ("POTTERY", "non-empty constructor", cps); - } - if (runflags->runtest[2]) { - c += timeTest (cps, testPOTTERY_smallnonemptyCtor, 100000); - print ("POTTERY", "small non-empty constructor", cps); - } - if (runflags->runtest[3]) { - c += timeTest (cps, testPOTTERY_cstrAssignment, 100000); - print ("POTTERY", "Char * assignment", cps); - } - if (runflags->runtest[4]) { - c += timeTest (cps, testPOTTERY_extraction, 100000); - print ("POTTERY", "char extraction", cps); - } - if (runflags->runtest[5]) { - c += timeTest (cps, testPOTTERY_scan, 100000); - print ("POTTERY", "scan", cps); - } - if (runflags->runtest[6]) { - c += timeTest (cps, testPOTTERY_concat, 10); - print ("POTTERY", "concatenation", cps * 250); - } -#endif - - return c; -} - -int main (int argc, char * argv[]) { - struct flags runflags; - int i, j; - - if (argc > 1 && strcmp(argv[1], "--csv") == 0) { - print_csv = true; - argc --; - argv++; - } - - for (i=0; i < NTESTS; i++) runflags.runtest[i] = argc < 2; - for (i=1; i < argc; i++) { - if (1 == sscanf (argv[i], "%d", &j)) { - if (j >= 1 && j <= NTESTS) runflags.runtest[j-1] = 1; - } - } - - benchTest (&runflags); - return 0; -} diff --git a/bench/bench-tommyds.c b/bench/bench-tommyds.c deleted file mode 100644 index 411899ab..00000000 --- a/bench/bench-tommyds.c +++ /dev/null @@ -1,221 +0,0 @@ -#define NDEBUG - -#include -#include -#include -#include - -#include "tommyds/tommy.h" - -#include "common.h" - -/********************************************************************************************/ - -static void test_array(size_t n) -{ - tommy_array a1, a2; - - tommy_array_init(&a1); - tommy_array_init(&a2); - for(size_t i = 0; i < n; i++) { - unsigned int v = rand_get(); - tommy_array_insert(&a1, (void*)(uintptr_t) v); - v = rand_get(); - tommy_array_insert(&a2, (void*)(uintptr_t) v); - } - unsigned int s = 0; - for(unsigned long i = 0; i < n; i++) { - s += (uintptr_t) *tommy_array_ref(&a1, i) * (uintptr_t) *tommy_array_ref(&a2, i ); - } - g_result = s; - tommy_array_done(&a1); - tommy_array_done(&a2); -} - -/********************************************************************************************/ - -struct list_node_s { - unsigned int value; - tommy_node node; -}; - -static void test_list (size_t n) -{ - tommy_list a1, a2; - - tommy_list_init(&a1); - tommy_list_init(&a2); - for(size_t i = 0; i < n; i++) { - struct list_node_s *obj; - obj = malloc(sizeof(struct list_node_s)); - if (obj == NULL) abort(); - obj->value = rand_get(); - tommy_list_insert_tail(&a1, &obj->node, obj); - obj = malloc(sizeof(struct list_node_s)); - if (obj == NULL) abort(); - obj->value = rand_get(); - tommy_list_insert_tail(&a2, &obj->node, obj); - } - unsigned int s = 0; - for(tommy_node *it1 = tommy_list_head(&a1), *it2 = tommy_list_head(&a2) - ; it1 != NULL; it1 = it1->next, it2 = it2->next ) { - struct list_node_s *obj1 = it1->data, *obj2 = it2->data; - s += obj1->value * obj2->value; - } - g_result = s; - tommy_list_foreach(&a1, free); - tommy_list_foreach(&a2, free); -} - -/********************************************************************************************/ - -struct tree_node_s { - unsigned long value; - tommy_tree_node node; -} ; - -static int compare(const void *a, const void *b) -{ - const struct tree_node_s *pa = a; - const struct tree_node_s *pb = b; - return (pa->value < pb->value) ? -1 : (pa->value > pb->value); -} - -static void test_rbtree(size_t n) -{ - tommy_tree tree; - tommy_tree_init(&tree, compare); - for (size_t i = 0; i < n; i++) { - struct tree_node_s *obj = malloc(sizeof(struct tree_node_s)); - if (obj == NULL) abort(); - obj->value = rand_get(); - tommy_tree_insert(&tree, &obj->node, obj); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - struct tree_node_s key = { .value = rand_get() }; - struct tree_node_s *obj = tommy_tree_search (&tree, &key); - if (obj) - s += obj->value; - } - g_result = s; - tommy_tree_foreach(&tree, free); -} - -/********************************************************************************************/ - -struct hash_i_node_s { - unsigned long key; - unsigned long value; - tommy_node node; -}; - -static inline size_t hash_func (const unsigned long key) -{ - return key; -} - -static int equal_func(const void* arg, const void *obj_p) -{ - const struct hash_i_node_s *obj = obj_p; - const unsigned long *key = arg; - return *key != obj->key; -} - -static void -test_dict(size_t n) -{ - tommy_hashlin dict; - tommy_hashlin_init(&dict); - for (size_t i = 0; i < n; i++) { - struct hash_i_node_s *obj = malloc(sizeof (struct hash_i_node_s)); - if(!obj) abort(); - obj->key = rand_get(); - obj->value = rand_get(); - tommy_hashlin_insert(&dict, &obj->node, obj, hash_func(obj->key)); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - unsigned long key = rand_get(); - struct hash_i_node_s *obj = tommy_hashlin_search(&dict, &equal_func, - &key, - hash_func(key)); - if (obj) - s += obj->value; - } - g_result = s; - tommy_hashlin_done(&dict); -} - -/********************************************************************************************/ - -typedef char char_array_t[256]; - -struct hash_b_node_s { - char_array_t key; - char_array_t value; - tommy_node node; -}; - -static int char_equal (const void *arg, const void *obj_p) -{ - const struct hash_b_node_s *obj = obj_p; - const char_array_t *key = (const char_array_t *)arg; - return strcmp(*key, (obj->key)); -} - -static size_t char_hash(const char *s) -{ - size_t hash = 0; - while (*s) hash = hash * 31421 + (*s++) + 6927; - return hash; -} - -static void -test_dict_big(size_t n) -{ - tommy_hashlin dict; - tommy_hashlin_init(&dict); - for (size_t i = 0; i < n; i++) { - struct hash_b_node_s *obj = malloc(sizeof (struct hash_b_node_s)); - if(!obj) abort(); - sprintf(obj->key, "%u", rand_get()); - sprintf(obj->value, "%u", rand_get()); - /* NOTE: this is not an insert_or_replace func... - It will always insert a new node, even if the key already exists... - Maybe searching then inserting will be a better representative? - */ - tommy_hashlin_insert(&dict, &obj->node, obj, char_hash(obj->key)); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_array_t s1; - sprintf(s1, "%u", rand_get()); - struct hash_b_node_s *obj = tommy_hashlin_search(&dict, &char_equal, - &s1, - char_hash(s1)); - if (obj) - s ++; - } - g_result = s; - tommy_hashlin_done(&dict); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 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("TommyDS", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-uthash.c b/bench/bench-uthash.c deleted file mode 100644 index ced00f7c..00000000 --- a/bench/bench-uthash.c +++ /dev/null @@ -1,215 +0,0 @@ -#define NDEBUG -#define _GNU_SOURCE - -#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(size_t 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(size_t 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); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 10, "List", 10000000, 0, test_list, 0}, - { 20, "Array", 100000000, 0, test_array, 0}, - { 40, "dict", 1000000, 0, test_dict, 0}, - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, - { 50, "sort", 10000000, 0, test_sort, 0} -}; - -int main(int argc, const char *argv[]) -{ - test("UT-HASH", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/bench-verstable.c b/bench/bench-verstable.c deleted file mode 100644 index 80aeda47..00000000 --- a/bench/bench-verstable.c +++ /dev/null @@ -1,94 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "m-core.h" -#include "common.h" - -#define NAME umap_ulong -#define KEY_TY unsigned long -#define VAL_TY unsigned long -#include "verstable.h" - -static void -test_dict(size_t n) -{ - umap_ulong dict; - umap_ulong_init(&dict); - - for (size_t i = 0; i < n; i++) { - unsigned long value = rand_get(); - unsigned long key = rand_get(); - umap_ulong_insert(&dict, key, value); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - umap_ulong_itr it = umap_ulong_get(&dict, rand_get()); - if (!umap_ulong_is_end(it) ) - s += it.data->val; - } - g_result = s; - - umap_ulong_cleanup(&dict); -} - -/********************************************************************************************/ - -#ifndef CHAR_ARRAY_SIZE -#define CHAR_ARRAY_SIZE 256 -#endif -typedef char char_array_t[CHAR_ARRAY_SIZE]; -typedef struct { char_array_t a; } char_encap;// Cannot use char_array_t directly -static bool char_equal_p (const char_encap a, const char_encap b) { return strcmp(a.a,b.a)==0; } -static size_t char_hash(const char_encap a) { return m_core_hash (a.a, strlen(a.a)); } - -#define NAME umap_char_array -#define KEY_TY char_encap -#define VAL_TY char_encap -#define HASH_FN char_hash -#define CMPR_FN char_equal_p -#include "verstable.h" - -static void -test_dict_big(size_t n) -{ - umap_char_array dict; - umap_char_array_init(&dict); - - for (size_t i = 0; i < n; i++) { - char_encap s1, s2; - - sprintf(s1.a, "%u", rand_get()); - sprintf(s2.a, "%u", rand_get()); - umap_char_array_insert(&dict, s1, s2); - } - rand_init(); - unsigned int s = 0; - for (size_t i = 0; i < n; i++) { - char_encap s1; - sprintf(s1.a, "%u", rand_get()); - umap_char_array_itr it = umap_char_array_get(&dict, s1); - if (!umap_char_array_is_end(it) ) - s ++; - } - g_result = s; - - umap_char_array_cleanup(&dict); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 40, "dict", 1000000, 0, test_dict, 0}, - { 41, "dictBig", 1000000, 0, test_dict_big, 0}, -}; - -int main(int argc, const char *argv[]) -{ - test("CTL", numberof(table), table, argc, argv); - exit(0); -} - diff --git a/bench/bench-xxhash.c b/bench/bench-xxhash.c deleted file mode 100644 index d4c598b7..00000000 --- a/bench/bench-xxhash.c +++ /dev/null @@ -1,42 +0,0 @@ -#define NDEBUG - -#include -#include -#include - -#include "xxhash.h" - -#include "common.h" - -static unsigned long *g_p; - -static void test_hash_prepare(size_t n) -{ - g_p = malloc (n * sizeof(unsigned long)); - if (g_p == NULL) abort(); - for(size_t i = 0; i < n ; i++) - g_p[i] = ((rand_get()*RAND_MAX + rand_get())*RAND_MAX+rand_get())*RAND_MAX + rand_get(); -} - - -static void test_hash_final(void) -{ - free(g_p); -} - -static void test_hash(size_t n) -{ - g_result = XXH64(g_p, sizeof(unsigned long)*n, 0); -} - -/********************************************************************************************/ - -const config_func_t table[] = { - { 70,"XXHASH64", 100000000, test_hash_prepare, test_hash, test_hash_final} -}; - -int main(int argc, const char *argv[]) -{ - test("XXHASH", numberof(table), table, argc, argv); - exit(0); -} diff --git a/bench/common.c b/bench/common.c deleted file mode 100644 index 8d15e965..00000000 --- a/bench/common.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * M*LIB - common functions for bench module - * - * Copyright (c) 2017-2024, Patrick Pelissier - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * + Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * + Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include "common.h" - -// Maximum supported value for repeat argument -#define MAX_REPEAT 10000 - -// The global result -unsigned long g_result; - -// The rand value -#if defined(MULTI_THREAD_MEASURE) -M_THREAD_ATTR -#endif -unsigned int randValue = 0; - -void compiler_barrier(void *p) -{ - // Do nothing, but let the compiler thinks that we did. - (void) p; - // Can be used for FLTO building - // asm volatile("": "+r" (p) : :"memory"); -} - -struct parse_opt_s { - int test_function; - double from, to, step, grow; - double within; - unsigned repeat; - bool graph, best, best_within, average, quiet; -}; - -static void -parse_config(struct parse_opt_s *opt, int argc, const char *argv[]) -{ - char *end; - - opt->test_function = 0; - opt->from = 0.0; - opt->to = 0.0; - opt->step = 0.0; - opt->grow = 1.1; - opt->graph = false; - opt->best = false; - opt->best_within = false; - opt->average = false; - opt->quiet = false; - opt->repeat = 1; - opt->within = .05; - - for(int i = 1; i < argc ; i++) - { - if (argv[i][0] == '-') { - if (strcmp(argv[i], "--from") == 0){ - i++; - opt->from = strtod(argv[i], &end); - opt->to = opt->from; - } else if (strcmp(argv[i], "--to") == 0) { - i++; - opt->to = strtod(argv[i], &end); - opt->grow = 1.1; - } else if (strcmp(argv[i], "--step") == 0) { - i++; - opt->step = strtod(argv[i], &end); - opt->grow = 0; - } else if (strcmp(argv[i], "--grow") == 0) { - i++; - opt->grow = strtod(argv[i], &end); - opt->step = 0; - } else if (strcmp(argv[i], "--repeat") == 0) { - i++; - opt->repeat = strtol(argv[i], &end, 10); - opt->repeat = (opt->repeat > MAX_REPEAT) ? MAX_REPEAT : opt->repeat; - } else if (strcmp(argv[i], "--graph") == 0) { - opt->graph = true; - } else if (strcmp(argv[i], "--best") == 0) { - opt->best = true; - opt->average = false; - opt->best_within = false; - } else if (strcmp(argv[i], "--best-within") == 0) { - opt->best_within = true; - opt->best = false; - opt->average = false; - i++; - opt->within = strtod(argv[i], &end) / 100.0; - } else if (strcmp(argv[i], "--average") == 0) { - opt->average = true; - opt->best = false; - opt->best_within = false; - } else if (strcmp(argv[i], "--quiet") == 0) { - opt->quiet = true; - } else { - fprintf(stderr, "ERROR: Option unkown: %s.\n", - argv[i]); - exit(-1); - } - if (*end != 0) { - fprintf(stderr, "ERROR: Cannot parse %s. Expected float\n", - argv[i]); - exit(-1); - } - - } else { - opt->test_function = strtol (argv[i], &end, 10); - if (*end != 0) { - fprintf(stderr, "ERROR: Cannot parse %s. Expected function number\n", - argv[i]); - exit(-1); - } - } - } -} - -static int -select_config(int func, size_t n, const config_func_t functions[]) -{ - for(size_t i = 0; i < n;i++) { - if (functions[i].num == func) - return i; - } - fprintf(stderr, "ERROR: Function number %d not found. Available functions are:\n", func); - for(size_t i = 0; i < n;i++) { - fprintf(stderr, " %d: %s\n", functions[i].num, functions[i].funcname); - } - fprintf(stderr, - "USAGE: FUNC_NUMBER [--from number --to number (--grow number | --step number)] [--graph]\n" - "[--repeat number] [--best|--average|--best-within] [--quiet]\n"); - exit(-1); -} - -// Utility function for qsort -static int cmp_double(const void *pa, const void *pb) -{ - const double *a = (const double *) pa, *b = (const double *)pb; - return (*a < *b) ? -1 : *a > *b; -} - -/* Get the longest sequence of values within 'f'% */ -static int -get_sequence(int i, int n, double tab[], double f) -{ - int j; - for(j = i + 1; j < n; j++) { - if (tab[j] > f * tab[i]) - break; - } - return j-i; -} - -/* Return the minimum of the longest sequence of values with 'f'% */ -static double -get_best_within(int n, double tab[], double f) -{ - qsort(tab, n, sizeof(double), cmp_double); - int best_i = 0; - int best_seq = get_sequence(0, n, tab, f); - for(int i = 1; i < n && (n-i) > best_seq ; i++) { - int seq = get_sequence(i, n, tab, f); - if (seq > best_seq) { - best_i = i; - best_seq = seq; - } - } - return tab[best_i]; -} - -// Integer sqrt function (to avoid depending on libm) -static unsigned integer_sqrt(unsigned n) -{ - // Find greatest shift. - int shift = 2; - unsigned nShifted = n >> shift; - // We check for nShifted being n, since some implementations - // perform shift operations modulo the word size. - while (nShifted != 0 && nShifted != n){ - shift += 2; - nShifted = n >> shift; - } - shift -= 2; - // Find digits of result. - unsigned result = 0; - while (shift >= 0) { - result = result << 1; - unsigned candidateResult = result + 1; - if (candidateResult*candidateResult <= n >> shift) { - result = candidateResult; - } - shift -= 2; - } - return result; -} - -void -test(const char library[], size_t n, const config_func_t functions[], int argc, const char *argv[]) -{ - // Init & parse arguments - // NUMBER - // --from NUMBER --to NUMBER --step NUMBER --grow NUMBER - // --graph --best --average --quiet - // --repeat N - struct parse_opt_s arg; - parse_config(&arg, argc, argv); - int i = select_config(arg.test_function, n, functions); - double from = (arg.from == 0) ? functions[i].default_n : arg.from; - double to = (arg.to == 0) ? functions[i].default_n : arg.to; - - // Open plot file if needed - FILE *graph_file = NULL; - if (arg.graph) { - char filename[100]; - sprintf(filename, "plot-%s-%d.dat", library, arg.test_function); - graph_file = fopen(filename, "wt"); - if (!graph_file) { - fprintf(stderr, "ERROR: Cannot create the file '%s'\n", filename); - exit(-2); - } - fprintf(graph_file, "# plotting %s-%d : %s\n# N T", library, arg.test_function, functions[i].funcname); - } - - // Do the bench - for(double n = from; n <= to ; n = ((arg.grow == 0) ? n + arg.step : n * arg.grow)) - { - double best = (1.0/0.0); - double avg = 0.0; - double variance = 0.0; - static double measure[MAX_REPEAT]; - double ba = 0.0; - - if (functions[i].init != NULL) - functions[i].init(n); - - // Measure the time of the test_function - for(unsigned r = 0; r < arg.repeat; r++) { - double t0 = test_function( (arg.graph|arg.best|arg.average|arg.quiet) ? NULL : functions[i].funcname, (size_t) n, functions[i].func); - best = (t0 < best) ? t0 : best; - avg += t0; - variance += t0 * t0; - measure[r] = t0; - } - - // Closure of the tests - if (functions[i].clear != NULL) - functions[i].clear(); - - // Finish computing the different times - if (arg.repeat > 1) { - avg /= arg.repeat; - variance = (variance - arg.repeat * avg * avg) / (arg.repeat - 1); - ba = get_best_within(arg.repeat, measure, 1. + arg.within); - } else { - ba = avg; - } - - // The average value shall be around best_within (and greater) - // otherwise the result doesn't seem reliable. - bool reliable = (ba <= avg && ba * (1.0+arg.within/2) + 0.5 > avg); - - // Print the result - if (arg.graph) { - fprintf(graph_file, "%f %f\n", n, arg.average ? avg : arg.best ? best : ba); - } else if (arg.quiet) { - printf("%ld\n", (long)(arg.average ? avg : arg.best ? best : reliable ? ba : -1)); - } else if (arg.repeat > 1) { - if (arg.average == false && arg.best_within == false) - printf ("%20.20s time %lu ms for n = %lu *** BEST ***\n", functions[i].funcname, (unsigned long) best, (unsigned long) n); - if (arg.best == false && arg.best_within == false) - printf ("%20.20s time %lu ms +/- %u ms for n = %lu *** AVERAGE ***\n", functions[i].funcname, (unsigned long) avg, 2*integer_sqrt(variance), (unsigned long) n); - if (arg.best == false && arg.average == false) - printf ("%20.20s time %lu ms for n = %lu *** BEST within %d%% *** %s\n", functions[i].funcname, (unsigned long) ba, (unsigned long) n, (int)(100*arg.within), reliable ? "" : "(unreliable result)"); - } - } - - // Close the FILE if needed - if (arg.graph) { - fclose(graph_file); - printf("File plot-%s-%d.dat generated.\n" - "Run in gnuplot the following command:\n" - "\tplot 'plot-%s-%d.dat' with linespoints linestyle 1\n", - library, arg.test_function, library, arg.test_function); - } - return; -} diff --git a/bench/common.h b/bench/common.h deleted file mode 100644 index aed8cf86..00000000 --- a/bench/common.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * M*LIB - common functions for bench module - * - * Copyright (c) 2017-2024, Patrick Pelissier - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * + Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * + Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#ifndef __COMMON_BENCH__H -#define __COMMON_BENCH__H - -#include -#include -#include - -// Needed for M_THREAD_ATTR -#if defined(MULTI_THREAD_MEASURE) -#include "m-thread.h" -#endif - -#if defined(_WIN32) -# include -#elif (defined(__APPLE__) && defined(__MACH__)) \ - || defined(__DragonFly__) || defined(__FreeBSD__) \ - || defined(__NetBSD__) || defined(__OpenBSD__) -# include -# include -# include -# include -# include -# define USE_SYSCTL -#else -# include -# include -# include -# include -#endif - -// Number of elements of a table -#define numberof(x) (sizeof(x)/sizeof(x[0])) - -/* Get the current CPU time in microsecond. */ -#if defined(_WIN32) -/* WINDOWS variant */ -static inline unsigned long long -cputime (void) -{ - LARGE_INTEGER freq, val; - QueryPerformanceFrequency(&freq); - QueryPerformanceCounter(&val); - return (unsigned long long) (1000000. * (double) val.QuadPart / (double) freq.QuadPart); -} -#else -/* UNIX variant */ -static inline unsigned long long -cputime (void) -{ -#if defined(MULTI_THREAD_MEASURE) - // Multi thread: Uses real time - struct timeval tv; - gettimeofday (&tv, NULL); - return tv.tv_sec * 1000000ULL + tv.tv_usec; -#else - // Single thread: Uses process usage time - struct rusage rus; - getrusage (0, &rus); - return rus.ru_utime.tv_sec * 1000000ULL + rus.ru_utime.tv_usec; -#endif -} - -#endif - -// The result of the bench -extern unsigned long g_result; - -// The rand value -extern -#if defined(MULTI_THREAD_MEASURE) -M_THREAD_ATTR -#endif -unsigned int randValue; - -// Pseudo rand value generator. -// Not very random but sufficient and fast enough for the bench -static inline void rand_init(void) -{ - randValue = 0; -} -static inline unsigned int rand_get(void) -{ - randValue = randValue * 31421U + 6927U; - return randValue; -} - -// The function that performs the bench -static inline double -test_function(const char *str, size_t n, void (*func)(size_t)) -{ - double result; - unsigned long long start, end; - rand_init(); - start = cputime(); - (*func)(n); - end = cputime(); - result = (double)(end-start) / 1000.0; - if (str != NULL) { - printf ("%20.20s time %.2f ms for n = %lu [r=%lu]\n", str, result, (unsigned long) n, g_result); - } - return result; -} - -// Configuration table -typedef struct { - int num; - const char *funcname; - size_t default_n; - void (*init)(size_t); - void (*func)(size_t); - void (*clear)(void); -} config_func_t; - -// Perform a parsing of the given arguments and do the bench according to the table -#ifdef __cplusplus -extern "C" -#endif -void test(const char library[], size_t n, const config_func_t functions[], int argc, const char *argv[]); - -/* Return the number of CPU of the system */ -static inline int get_cpu_count(void) -{ -#if defined(_WIN32) - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - return sysinfo.dwNumberOfProcessors; -#elif defined(USE_SYSCTL) - int nm[2]; - int count = 0; - size_t len = sizeof (count); - nm[0] = CTL_HW; - nm[1] = HW_NCPU; - sysctl(nm, 2, &count, &len, NULL, 0); - return MAX(1, count); -#elif defined (_SC_NPROCESSORS_ONLN) - return sysconf(_SC_NPROCESSORS_ONLN); -#else - return 1; -#endif -} - -#ifdef __cplusplus -extern "C" -#endif -void compiler_barrier(void *p); - -#endif diff --git a/bench/max-dict.c b/bench/max-dict.c deleted file mode 100644 index 10099ed0..00000000 --- a/bench/max-dict.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * MLIB - TEST module - * - * Copyright (c) 2017-2024, Patrick Pelissier - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * + Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * + Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#include -#include -#include - -#define NDEBUG -#include "m-dict.h" - -static inline bool oor_equal_p(int64_t k, unsigned char n) -{ - return k == (int)-n-1; -} -static inline void oor_set(int64_t *k, unsigned char n) -{ - *k = (int)-n-1; -} - -DICT_OA_DEF2(dict_int64, int64_t, M_OPEXTEND(M_DEFAULT_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)), int64_t, M_DEFAULT_OPLIST) - -static int64_t get_rand(void) -{ - int64_t n; - do { - n = (rand() * RAND_MAX + rand()) * RAND_MAX + rand(); - } while (n == -1 || n == -2); - return n; -} - -// Let's push value into the dict until the system abandons! -static void find_max(void) -{ - dict_int64_t dict; - dict_int64_init(dict); - size_t n = 0; - while (true) { - dict_int64_set_at (dict, get_rand(), get_rand()); - n++; - if ((n & ((1<<20)-1)) == 0) { - printf ("n=%zu\n", n); - } - } - dict_int64_clear(dict); -} - -int main() -{ - find_max(); -} diff --git a/bench/nucleotide/Makefile b/bench/nucleotide/Makefile deleted file mode 100644 index b3033e9d..00000000 --- a/bench/nucleotide/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -CC=cc -std=c11 -CXX=c++ -std=c++11 -CFLAGS=-O2 -march=native -Wall -CPPFLAGS=-I../.. - -all: k-nucleotide - -k-nucleotide: k-nucleotide.exe data.txt - ./k-nucleotide.exe < data.txt - -k-nucleotide.exe: nucleotide.c - $(CC) $(CFLAGS) $(CPPFLAGS) nucleotide.c -o k-nucleotide.exe -lpthread - -data.txt: fasta.exe - ./fasta.exe 25000000 > data.txt - -fasta.exe: fasta.c - $(CC) $(CFLAGS) $(CPPFLAGS) -fopenmp fasta.c -o fasta.exe - -clean: - rm -f *.exe *~ *.o data.txt - diff --git a/bench/nucleotide/fasta.c b/bench/nucleotide/fasta.c deleted file mode 100644 index d27ce3ba..00000000 --- a/bench/nucleotide/fasta.c +++ /dev/null @@ -1,344 +0,0 @@ -// The Computer Language Benchmarks Game -// http://benchmarksgame.alioth.debian.org/ -// -// contributed by Jeremy Zerfas -// rewritten by Аноним Легионов, inspired by fasta Rust #2 program -// use two OpenMP locks instead of one critical section -// decouples IO activity from random number generation -// -// modified by Josh Goldfoot, adding use of a buffer for fasta_repeat - - -// This controls the width of lines that are output by this program. -#define MAXIMUM_LINE_WIDTH 60 - -// This program will generate the random nucleotide sequences in parallel which -// are worked on in blocks of lines. The number of lines in those blocks is -// controlled by this setting. -#define LINES_PER_BLOCK 1024 - -#define CHARACTERS_PER_BLOCK (MAXIMUM_LINE_WIDTH*LINES_PER_BLOCK) - -#define THREADS_TO_USE 4 - -#include -#include -#include -#include - -#ifdef _OPENMP -#include -#endif - -// intptr_t should be the native integer type on most sane systems. -typedef intptr_t intnative_t; - -typedef struct -{ - char letter; - float probability; -} nucleotide_info; - - -// Repeatedly print string_To_Repeat until it has printed -// number_Of_Characters_To_Create. The output is also wrapped to -// MAXIMUM_LINE_WIDTH columns. -static char* make_Sequence_Buffer(const char string_To_Repeat[]) -{ - const intnative_t string_To_Repeat_Length = strlen(string_To_Repeat); - - // JG: Changed to that this writes a sequence to a buffer, which is used - intnative_t number_Of_Characters_To_Create = string_To_Repeat_Length * MAXIMUM_LINE_WIDTH; - char* buffer = (char*) malloc(number_Of_Characters_To_Create + - number_Of_Characters_To_Create / MAXIMUM_LINE_WIDTH + 1); - if (buffer == NULL) - exit(-1); - char* bufferOffset = buffer; - - // Create an extended_String_To_Repeat which is a copy of string_To_Repeat - // but extended with another copy of the first MAXIMUM_LINE_WIDTH characters - // of string_To_Repeat appended to the end. Later on this allows us to - // generate a line of output just by doing simple memory copies using an - // appropriate offset into extended_String_To_Repeat. - char extended_String_To_Repeat[string_To_Repeat_Length + MAXIMUM_LINE_WIDTH]; - for (intnative_t column = 0; column0;) - { - // Figure out the length of the line we need to write. If it's less than - // MAXIMUM_LINE_WIDTH then we also need to add a line feed in the right - // spot too. - intnative_t line_Length = MAXIMUM_LINE_WIDTH; - if (current_Number_Of_Characters_To_Createstring_To_Repeat_Length) - offset -= string_To_Repeat_Length; - - // "Output" that line to our buffer and update the - // current_Number_Of_Characters_To_Create. - memcpy(bufferOffset, line, line_Length + 1); // JG: used to be fwrite(line, line_Length + 1, 1, stdout); - bufferOffset += line_Length + 1; - current_Number_Of_Characters_To_Create -= line_Length; - } - *bufferOffset = 0; - return buffer; -} - -void repeat_And_Wrap_String(const char string_To_Repeat[], intnative_t number_Of_Characters_To_Create) -{ - /* JG: fasta_repeat repeats every len(alu) * line-length = 287 * 61 = 17507 characters. - So, calculate this once, then just print that buffer over and over. */ - char* sequence = make_Sequence_Buffer(string_To_Repeat); - intnative_t sequenceLen = (intnative_t) strlen(sequence); - intnative_t outputBytes = number_Of_Characters_To_Create + number_Of_Characters_To_Create / 60; - while (outputBytes >= sequenceLen) { - fwrite(sequence, sequenceLen, 1, stdout); - outputBytes -= sequenceLen; - } - if (outputBytes > 0) { - fwrite(sequence, outputBytes, 1, stdout); - printf("\n"); - } - free(sequence); -} - - -// Generate a pseudorandom number from 0 to max using a linear -// congruential generator. -#define IM 139968 -#define IA 3877 -#define IC 29573 -uint32_t seed = 42; - -int rng_tid; //Thread ID -int rng_tnum = 1; //Thread number -intnative_t rng_cnt = 0; - -#ifdef _OPENMP -omp_lock_t rng_lock; -#define RNG_LOCK_INIT() omp_init_lock(&rng_lock) -#define RNG_LOCK() omp_set_lock(&rng_lock) -#define RNG_FREE() omp_unset_lock(&rng_lock) -#else -#define RNG_LOCK_INIT() do{}while(0) -#define RNG_LOCK() do{}while(0) -#define RNG_FREE() do{}while(0) -#endif - -static void rng_init(void) -{ - RNG_LOCK_INIT(); - rng_tid = 0; -} - -static intnative_t rng_gen_blk(uint32_t * buf, intnative_t len, int curr_tid) -{ - intnative_t gen_cnt = -1;//Error by default - RNG_LOCK(); - - if (rng_tid == curr_tid) - { - if (++rng_tid >= rng_tnum) - { - rng_tid = 0; - } - - gen_cnt = (len= out_tnum) - { - out_tid = 0; - } - wr_cnt = fwrite(buf, len, 1, stdout); - } - - OUT_FREE(); - return wr_cnt; //-1 - thread error, 0 - IO error, 1 - ОК -} - -static void generate_And_Wrap_Pseudorandom_DNA_Sequence( - const nucleotide_info nucl_info[], - const intnative_t nucl_num, - const intnative_t char_num) -{ - uint32_t cumul_p[nucl_num]; - float cumul_acc = 0.0; - - for (intnative_t i = 0; iTHREADS_TO_USE) tnum = THREADS_TO_USE; - omp_set_num_threads(tnum); - rng_tnum = tnum; - out_tnum = tnum; -#endif - rng_tid = 0; - out_tid = 0; - rng_cnt = char_num; - -#pragma omp parallel - { - char block[CHARACTERS_PER_BLOCK + LINES_PER_BLOCK]; - char * line; - uint32_t rnd[CHARACTERS_PER_BLOCK], r; - intnative_t cnt, col, prid, nid, ncnt; - int cur_tid; -#ifdef _OPENMP - cur_tid = omp_get_thread_num(); -#else - cur_tid = 0; -#endif - while (1) - { - do - { - cnt = rng_gen_blk(rnd, CHARACTERS_PER_BLOCK, cur_tid); - } while (-1 == cnt); - - if (0 == cnt) - { - break;//Work finished! - } - - line = block; - - for (col = 0, prid = 0; prid < cnt; prid++) - { - r = rnd[prid]; - - ncnt = 0; - for (nid = 0; nid < nucl_num; nid++) - { - if (cumul_p[nid] <= r) - { - ncnt++; - } - } - - *line++ = nucl_info[ncnt].letter; - if (++col >= MAXIMUM_LINE_WIDTH) - { - col = 0; - *line++ = '\n'; - } - } - //Check if we need to end the line - if (0 != col) - { - //Last iteration didn't end the line, so finish the job. - *line++ = '\n'; - } - //Print results - do - { - cnt = out_write(block, line - block, cur_tid); - } while (-1 == cnt); - //Check fot IO error - if (0 == cnt) - { - exit(1); - } - } - } -} - - -int main(int argc, char ** argv) -{ - const intnative_t n = atoi(argv[1]); - - fputs(">ONE Homo sapiens alu\n", stdout); - const char homo_Sapiens_Alu[] = - "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTC" - "AGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCG" - "TGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGG" - "AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; - repeat_And_Wrap_String(homo_Sapiens_Alu, 2 * n); - - rng_init(); - out_init(); - - fputs(">TWO IUB ambiguity codes\n", stdout); - nucleotide_info iub_Nucleotides_Information[] = - { - { 'a', 0.27 },{ 'c', 0.12 },{ 'g', 0.12 },{ 't', 0.27 },{ 'B', 0.02 }, - { 'D', 0.02 },{ 'H', 0.02 },{ 'K', 0.02 },{ 'M', 0.02 },{ 'N', 0.02 }, - { 'R', 0.02 },{ 'S', 0.02 },{ 'V', 0.02 },{ 'W', 0.02 },{ 'Y', 0.02 } - }; - generate_And_Wrap_Pseudorandom_DNA_Sequence(iub_Nucleotides_Information, - sizeof(iub_Nucleotides_Information) / sizeof(nucleotide_info), 3 * n); - - fputs(">THREE Homo sapiens frequency\n", stdout); - nucleotide_info homo_Sapien_Nucleotides_Information[] = - { - { 'a', 0.3029549426680 },{ 'c', 0.1979883004921 }, - { 'g', 0.1975473066391 },{ 't', 0.3015094502008 } - }; - generate_And_Wrap_Pseudorandom_DNA_Sequence(homo_Sapien_Nucleotides_Information, - sizeof(homo_Sapien_Nucleotides_Information) / sizeof(nucleotide_info), 5 * n); - - return 0; -} diff --git a/bench/nucleotide/nucleotide.c b/bench/nucleotide/nucleotide.c deleted file mode 100644 index be8eed35..00000000 --- a/bench/nucleotide/nucleotide.c +++ /dev/null @@ -1,266 +0,0 @@ -// The Computer Language Benchmarks Game -// http://benchmarksgame.alioth.debian.org/ -// -// Original version Contributed by Jeremy Zerfas -// M*LIB port contributed by Patrick Pélissier -#define NDEBUG -#include -#include -#include -#include -#include - -#include "m-worker.h" -#include "m-dict.h" -#include "m-bptree.h" - -// This controls the maximum length for each set of oligonucleotide frequencies -// and each oligonucleotide count output by this program. -#define MAXIMUM_OUTPUT_LENGTH 4096 - -// Number of outputs to display -#define MAXMUM_NUMBER_OUTPUT 7 - -/* Define the needed containers */ -/* Define Open Addressing dictionary of uint64_t --> uint32_t. Need to define how to handle out of bound data. */ -static inline bool my_oor_equal_p(uint64_t k, unsigned char n) -{ - return k == ~(uint64_t) n; -} -static inline void my_oor_set(uint64_t *k, unsigned char n) -{ - *k = ~(uint64_t)n; -} -static inline size_t my_hash(uint64_t key) -{ - return ((key) ^ (key)>>7); -} -DICT_OA_DEF2(dict_oligonucleotide, - uint64_t, M_OPEXTEND(M_DEFAULT_OPLIST, HASH(my_hash), OOR_EQUAL(my_oor_equal_p), OOR_SET(my_oor_set M_IPTR)), - uint32_t, M_DEFAULT_OPLIST) -#define M_OPL_dict_oligonucleotide_t() DICT_OPLIST(dict_oligonucleotide, M_OPEXTEND(M_DEFAULT_OPLIST, HASH(my_hash), OOR_EQUAL(my_oor_equal_p), OOR_SET(my_oor_set M_IPTR)), M_DEFAULT_OPLIST) - -// Define a B*TREE-21 of uint32_t --> uint64_t and register its oplist -#define TREE_CMP(a,b) ((a) > (b) ? -1 : (a) < (b)) /* reverse natural order */ -BPTREE_DEF2(tree_dict_oligonucleotide, 21, uint32_t, M_OPEXTEND(M_DEFAULT_OPLIST, CMP(TREE_CMP)), uint64_t, M_DEFAULT_OPLIST) -#define M_OPL_tree_dict_oligonucleotide_t() BPTREE_OPLIST2(tree_dict_oligonucleotide, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST) - -/* Define the data to analyse (a plain array) */ -ARRAY_DEF(polynucleotide, unsigned char) - -// Macro to convert a nucleotide character to a code. Note that upper and lower -// case ASCII letters only differ in the fifth bit from the right and we only -// need the three least significant bits to differentiate the letters 'A', 'C', -// 'G', and 'T'. Spaces in this array/string will never be used as long as -// characters other than 'A', 'C', 'G', and 'T' aren't used. -#define CODE_FOR_NUCLEOTIDE(nucleotide) (" \0 \1\3 \2"[nucleotide & 0x7]) - -// And one more macro to convert the codes back to nucleotide characters. -#define NUCLEOTIDE_FOR_CODE(code) ("ACGT"[code & 0x3]) - -static worker_t worker; - -// Read from the given stream the data and fill in the array with the converted one. -static void polynucleotide_init_stream(polynucleotide_t p, FILE *stream) -{ - char buffer[MAXIMUM_OUTPUT_LENGTH], c; - - polynucleotide_init(p); - polynucleotide_reserve(p, MAXIMUM_OUTPUT_LENGTH); - // Find the start of the third polynucleotide. - while(fgets(buffer, sizeof(buffer), stream) && memcmp(">THREE", buffer, 6)); - // Start reading and encoding the third polynucleotide. - while(fgets(buffer, sizeof(buffer), stream) && buffer[0]!='>'){ - for(size_t i = 0; (c = buffer[i]) !='\0'; i++) { - if (c != '\n') { - polynucleotide_push_back(p, CODE_FOR_NUCLEOTIDE(c)); - } - } - } -} - -// This is the function which does 95% of the work. -/* NOTE: paralelisation is not done by cutting the input set in two. - This is not efficient as the size of the output table will be the same - as for the whole table. */ -static void init_hash(dict_oligonucleotide_t hash_Table, const size_t size, const unsigned char tab[size], const size_t desiredLength, const size_t offset, const size_t skip) -{ - uint64_t key = 0; - const uint64_t mask = (1ULL<<(2*desiredLength))-1; - assert (2*desiredLength < 64 && desiredLength < size); - assert ((1 == skip || 4 == skip) && offset < size); - - // For the first several nucleotides we only need to append them to key in - // preparation for the insertion of complete oligonucleotides to hash. - for(size_t i = 0; i < desiredLength - 1 + offset; i++) - key = (key<<2) | tab[i]; - key &= mask; - - dict_oligonucleotide_t hash; - dict_oligonucleotide_init(hash); - - // Add all the complete oligonucleotides of - // desiredLength to hash, updating their count - if (skip == 1) { - for(size_t i = desiredLength-1+offset ; i < size; i++) { - key = (key<<2) | tab[i+0]; - key &= mask; - uint32_t *p = dict_oligonucleotide_get(hash, key); - if (p != NULL) { - (*p) ++; - } else { - dict_oligonucleotide_set_at(hash, key, 1); - } - } - } else { // skip = 4 - for(size_t i = desiredLength-1+offset ; i < size; i+=4) { - for (size_t j = 0; j < 4; j++) - key = (key<<2) | tab[i+j]; - key &= mask; - uint32_t *p = dict_oligonucleotide_get(hash, key); - if (p != NULL) { - (*p) ++; - } else { - dict_oligonucleotide_set_at(hash, key, 1); - } - } - } - dict_oligonucleotide_init_move(hash_Table, hash); -} - -static void compute_hash(dict_oligonucleotide_t hash_Table, const polynucleotide_t p, const size_t desiredLength) -{ - size_t size = polynucleotide_size(p); - unsigned char *tab = polynucleotide_get(p, 0); - if (desiredLength < 8) { - init_hash(hash_Table, size, tab, desiredLength, 0, 1); - return; - } - - worker_sync_t block; // Define a synchronization block - worker_start(block, worker); - dict_oligonucleotide_t hash_Table3, *p_hash_Table3 = &hash_Table3; - dict_oligonucleotide_t hash_Table2, *p_hash_Table2 = &hash_Table2; - dict_oligonucleotide_t hash_Table1, *p_hash_Table1 = &hash_Table1; - WORKER_SPAWN(block, (p_hash_Table1, size, tab, desiredLength), { - init_hash(*p_hash_Table1, size, tab, desiredLength, 3, 4); - }, (/*no output*/)); - WORKER_SPAWN(block, (p_hash_Table2, size, tab, desiredLength), { - init_hash(*p_hash_Table2, size, tab, desiredLength, 2, 4); - }, (/*no output*/)); - WORKER_SPAWN(block, (p_hash_Table3, size, tab, desiredLength), { - init_hash(*p_hash_Table3, size, tab, desiredLength, 1, 4); - }, (/*no output*/)); - init_hash(hash_Table, size, tab, desiredLength, 0, 4); - worker_sync(block); - - // Merge all hashtables - dict_oligonucleotide_splice(hash_Table, hash_Table1); - dict_oligonucleotide_splice(hash_Table, hash_Table2); - dict_oligonucleotide_splice(hash_Table, hash_Table3); - // Clear extra hashtables - dict_oligonucleotide_clear(hash_Table3); - dict_oligonucleotide_clear(hash_Table2); - dict_oligonucleotide_clear(hash_Table1); -} - -// Generate frequencies for all oligonucleotides in polynucleotide that are of -// desiredLength and then save it to output. -static void compute_freq(const polynucleotide_t p, const size_t desiredLength, char output[]) -{ - dict_oligonucleotide_t hash_Table; - compute_hash(hash_Table, p, desiredLength); - - // Order key is the count frequency (inverse value & key) - tree_dict_oligonucleotide_t tree; - tree_dict_oligonucleotide_init(tree); - for M_EACH(item, hash_Table, dict_oligonucleotide_t) { - tree_dict_oligonucleotide_set_at (tree, item->value, item->key); - } - - // Create Output - char oligonucleotide[64]; - const double invSum = 100.0 / (double) (polynucleotide_size(p) - desiredLength + 1); - int output_Position = 0; - for M_EACH(item, tree, tree_dict_oligonucleotide_t) { - // Convert the key for the oligonucleotide to a string. - uint64_t freq = *item->value_ptr; - uint32_t count = *item->key_ptr; - for(size_t j = desiredLength-1; j < desiredLength; j--){ - oligonucleotide[j]=NUCLEOTIDE_FOR_CODE(freq); - freq>>=2; - } - oligonucleotide[desiredLength]='\0'; - // Output the frequency for oligonucleotide to output. - output_Position+=snprintf(output+output_Position, MAXIMUM_OUTPUT_LENGTH-output_Position, - "%s %.3f\n", oligonucleotide, invSum * count); - } - - dict_oligonucleotide_clear(hash_Table); - tree_dict_oligonucleotide_clear(tree); -} - -// Generate a count for the number of times oligonucleotide appears in -// polynucleotide and then save it to output. -static void compute_count(polynucleotide_t p, const char oligonucleotide[], char output[]) -{ - const size_t oligonucleotide_Length = strlen(oligonucleotide); - dict_oligonucleotide_t hash_Table; - compute_hash(hash_Table, p, oligonucleotide_Length); - - // Generate the key for oligonucleotide. - uint64_t key=0; - for(size_t i=0; i -#include - -#include -#include -#include -#include -#include - -#ifdef USE_BOOST -#include -#endif - -#ifdef USE_GLIB -#include -#endif - -static const size_t PAGE_SIZE = 4096; - -// sizeof(TfwStr) -struct Small { - long l[3]; - - std::string - operator+(const char *str) - { return std::string(str) + " (Small)"; } -}; - -// size of common HTTP headers table -struct Big { - Small s[10]; - - std::string - operator+(const char *str) - { return std::string(str) + " (Big)"; } -}; - -// very big allocation -struct Huge { - char c[PAGE_SIZE * 2 + 113]; - - std::string - operator+(const char *str) - { return std::string(str) + " (Huge)"; } -}; - -static const size_t N = 20 * 1000 * 1000; - -void -benchmark(std::string &&desc, std::function cb) -{ - using namespace std::chrono; - - // steady_clock has the same resolution as high_resolution_clock - auto t(steady_clock::now()); - - cb(); - - auto dt = steady_clock::now() - t; - std::cout << std::setw(30) << std::right << desc << ": " - << duration_cast(dt).count() - << "ms" << std::endl; -} - -#define touch_obj(o) \ - if (__builtin_expect(!o, 0)) { \ - std::cerr << "failed alloc" << std::endl; \ - break; \ - } else { \ - *(long *)o = 1; \ - } - -/* - * ------------------------------------------------------------------------ - * Boost::pool - * ------------------------------------------------------------------------ - */ -#ifdef USE_BOOST - -template -void -benchmark_boost_pool() -{ - boost::object_pool p; - - benchmark(std::move(T() + "boost::pool"), [&]() { - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = p.malloc(); - touch_obj(o); - } - }); -} - -template -void -benchmark_boost_pool_free() -{ - boost::object_pool p; - - benchmark(std::move(T() + "boost::pool w/ free"), [&]() { - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = p.malloc(); - touch_obj(o); - if (__builtin_expect(!(i & 3), 0)) - p.free(o); - } - }); -} - -void -benchmark_boost_pool_create_and_destroy() -{ - benchmark(std::move(std::string("boost::pool cr. & destr.")), []() { - for (size_t i = 0; i < N / 100; ++i) { - if (__builtin_expect(!(i & 3), 0)) { - boost::object_pool p; - for (size_t j = 0; j < 100; ++j) { - Big *o = p.malloc(); - touch_obj(o); - } - } else { - boost::object_pool p; - for (size_t j = 0; j < 100; ++j) { - Small *o = p.malloc(); - touch_obj(o); - } - } - } - }); -} -#endif - -/* - * ------------------------------------------------------------------------ - * malloc/free - * ------------------------------------------------------------------------ - */ -template -void -benchmark_mallocfree() -{ - benchmark(std::move(T() + "mallocfree"), [&]() { - static __thread T *ptrs[N * sizeof(Small) / sizeof(T)]; - - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = (T*)malloc(sizeof(T)); - ptrs[i] = o; - touch_obj(o); - } - - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - free(ptrs[i]); - } - }); -} - -template -void -benchmark_mallocfree_free() -{ - benchmark(std::move(T() + "mallocfree w/ free"), [&]() { - static __thread T *ptrs[N * sizeof(Small) / sizeof(T)]; - - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = (T*)malloc(sizeof(T)); - ptrs[i] = o; - touch_obj(o); - - if (__builtin_expect(!(i & 3), 0)) { - free(o); - ptrs[i] = NULL; - } - } - - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - free(ptrs[i]); - } - }); -} - -/* - * ------------------------------------------------------------------------ - * GLib slices - * ------------------------------------------------------------------------ - */ -#ifdef USE_GLIB -template -void -benchmark_glib_slices() -{ - benchmark(std::move(T() + "GLib slices"), [&]() { - static __thread T *ptrs[N * sizeof(Small) / sizeof(T)]; - - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = (T*)g_slice_alloc(sizeof(T)); - ptrs[i] = o; - touch_obj(o); - } - - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - g_slice_free1(sizeof(T), ptrs[i]); - } - }); -} - -template -void -benchmark_glib_slices_free() -{ - benchmark(std::move(T() + "GLib slices w/ free"), [&]() { - static __thread T *ptrs[N * sizeof(Small) / sizeof(T)]; - - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = (T*)g_slice_alloc(sizeof(T)); - ptrs[i] = o; - touch_obj(o); - - if (__builtin_expect(!(i & 3), 0)) { - g_slice_free1(sizeof(T), o); - ptrs[i] = NULL; - } - } - - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - g_slice_free1(sizeof(T), ptrs[i]); - } - }); -} -#endif - -/* - * ------------------------------------------------------------------------ - * Nginx pool - * Simplified version of src/core/ngx_palloc.c from nginx-1.9.5 with - * some code adjustments to be built in this benchmark. - * ------------------------------------------------------------------------ - */ -struct ngx_pool_t; -typedef uintptr_t ngx_uint_t; - -#define NGX_POOL_ALIGNMENT 16 -#define NGX_ALIGNMENT sizeof(unsigned long) -#define ngx_align_ptr(p, a) \ - (u_char *)(((uintptr_t)(p) + ((uintptr_t)a - 1)) & ~((uintptr_t)a - 1)) -#define NGX_MAX_ALLOC_FROM_POOL ((size_t)PAGE_SIZE - 1) - -struct ngx_pool_data_t { - unsigned char *last; - unsigned char *end; - ngx_pool_t *next; - unsigned int failed; -}; - -struct ngx_pool_large_t { - ngx_pool_large_t *next; - void *alloc; -}; - -struct ngx_pool_t { - ngx_pool_data_t d; - size_t max; - ngx_pool_t *current; - ngx_pool_large_t *large; -}; - -ngx_pool_t * -ngx_create_pool(size_t size) -{ - ngx_pool_t *p; - - if (posix_memalign((void **)&p, NGX_POOL_ALIGNMENT, size)) - return NULL; - - p->d.last = (unsigned char *)p + sizeof(ngx_pool_t); - p->d.end = (unsigned char *)p + size; - p->d.next = NULL; - p->d.failed = 0; - - size = size - sizeof(ngx_pool_t); - p->max = (size < NGX_MAX_ALLOC_FROM_POOL) - ? size : NGX_MAX_ALLOC_FROM_POOL; - - p->current = p; - p->large = NULL; - - return p; -} - -void -ngx_destroy_pool(ngx_pool_t *pool) -{ - ngx_pool_t *p, *n; - ngx_pool_large_t *l; - - for (l = pool->large; l; l = l->next) { - if (l->alloc) - free(l->alloc); - } - - for (p = pool, n = pool->d.next; ; p = n, n = n->d.next) { - free(p); - if (n == NULL) - break; - } -} - -static void * -ngx_palloc_block(ngx_pool_t *pool, size_t size) -{ - unsigned char *m; - size_t psize = (size_t)(pool->d.end - (unsigned char *)pool); - ngx_pool_t *p, *p_new; - - if (posix_memalign((void **)&m, NGX_POOL_ALIGNMENT, psize)) - return NULL; - p_new = (ngx_pool_t *)m; - - p_new->d.end = m + psize; - p_new->d.next = NULL; - p_new->d.failed = 0; - - m += sizeof(ngx_pool_data_t); - m = ngx_align_ptr(m, NGX_ALIGNMENT); - p_new->d.last = m + size; - - for (p = pool->current; p->d.next; p = p->d.next) { - if (p->d.failed++ > 4) - pool->current = p->d.next; - } - p->d.next = p_new; - - return m; -} - -void *ngx_palloc(ngx_pool_t *pool, size_t size); - -static void * -ngx_palloc_large(ngx_pool_t *pool, size_t size) -{ - void *p; - unsigned int n = 0; - ngx_pool_large_t *large; - - p = malloc(size); - if (p == NULL) - return NULL; - - for (large = pool->large; large; large = large->next) { - if (large->alloc == NULL) { - large->alloc = p; - return p; - } - if (n++ > 3) - break; - } - - large = (ngx_pool_large_t *)ngx_palloc(pool, sizeof(ngx_pool_large_t)); - if (large == NULL) { - free(p); - return NULL; - } - - large->alloc = p; - large->next = pool->large; - pool->large = large; - - return p; -} - -void * -ngx_palloc(ngx_pool_t *pool, size_t size) -{ - unsigned char *m; - ngx_pool_t *p; - - if (size <= pool->max) { - p = pool->current; - do { - m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT); - if ((size_t)(p->d.end - m) >= size) { - p->d.last = m + size; - return m; - } - p = p->d.next; - } while (p); - - return ngx_palloc_block(pool, size); - } - - return ngx_palloc_large(pool, size); -} - -void -ngx_pfree(ngx_pool_t *pool, void *p) -{ - ngx_pool_large_t *l; - - for (l = pool->large; l; l = l->next) { - if (p == l->alloc) { - free(l->alloc); - l->alloc = NULL; - return; - } - } -} - -template -void -benchmark_ngx_pool() -{ - ngx_pool_t *p = ngx_create_pool(PAGE_SIZE); - assert(p); - - benchmark(std::move(T() + "ngx_pool"), [=]() { - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = (T *)ngx_palloc(p, sizeof(T)); - touch_obj(o); - } - }); - - ngx_destroy_pool(p); -} - -void -benchmark_ngx_pool_mix_free() -{ - ngx_pool_t *p = ngx_create_pool(PAGE_SIZE); - assert(p); - - benchmark(std::move(std::string("ngx_pool w/ free (Mix)")), [=]() { - for (size_t i = 0; i < N; ++i) { - if (__builtin_expect(!(i & 0xfff), 0)) { - Huge *o; - o = (Huge *)ngx_palloc(p, sizeof(*o)); - touch_obj(o); - if (!(i & 1)) - ngx_pfree(p, o); - } - else if (__builtin_expect(!(i & 3), 0)) { - Big *o = (Big *)ngx_palloc(p, sizeof(*o)); - touch_obj(o); - if (!(i & 1)) - ngx_pfree(p, o); - } - else { - Small *o = (Small *)ngx_palloc(p, sizeof(*o)); - touch_obj(o); - if (!(i & 1)) - ngx_pfree(p, o); - } - } - }); - - ngx_destroy_pool(p); -} - -void -benchmark_ngx_pool_create_and_destroy() -{ - benchmark(std::move(std::string("ngx_pool cr. & destr.")), []() { - for (size_t i = 0; i < N / 100; ++i) { - ngx_pool_t *p = ngx_create_pool(PAGE_SIZE); - for (size_t j = 0; j < 100; ++j) { - if (__builtin_expect(!(i & 3), 0)) { - Big *o; - o = (Big *)ngx_palloc(p, sizeof(*o)); - touch_obj(o); - } else { - Small *o; - o = (Small *)ngx_palloc(p, sizeof(*o)); - touch_obj(o); - } - } - ngx_destroy_pool(p); - } - }); -} - -/* - * ------------------------------------------------------------------------ - * Tempesta FW pool - * Simplified and ported to user-space from - * https://github.com/natsys/tempesta/blob/master/tempesta_fw/pool.c - * ------------------------------------------------------------------------ - */ -/** - * Emulation of Linux buddy allocator. - */ -#define GFP_ATOMIC 0 -#define PAGE_MASK (~(PAGE_SIZE - 1)) -#define likely(x) __builtin_expect(x, 1) -#define unlikely(x) __builtin_expect(x, 0) -#define free_pages(p, o) free((void *)(p)) -#define get_order(n) (assert((n) < PAGE_SIZE * 128), \ - (n) < PAGE_SIZE ? 0 \ - : (n) < PAGE_SIZE * 2 ? 1 \ - : (n) < PAGE_SIZE * 4 ? 2 \ - : (n) < PAGE_SIZE * 8 ? 3 \ - : (n) < PAGE_SIZE * 16 ? 4 \ - : (n) < PAGE_SIZE * 32 ? 5 \ - : (n) < PAGE_SIZE * 64 ? 6 \ - : 7) - -static inline unsigned long -__get_free_pages(int flags __attribute__((unused)), int order) -{ - void *p; - - if (posix_memalign((void **)&p, PAGE_SIZE, PAGE_SIZE << order)) - return 0; - - return (unsigned long)p; -} - -/** - * Memory pool chunk descriptor. - * - * @next - pointer to next memory chunk; - * @order - order of number of pages in the chunk; - * @off - current chunk offset; - */ -struct TfwPoolChunk { - TfwPoolChunk *next; - unsigned int order; - unsigned int off; -}; - -/** - * Memory pool descriptor. - * - * @curr - current chunk to allocate memory from; - * @order,@off - cached members of @curr; - */ -typedef struct { - TfwPoolChunk *curr; - unsigned int order; - unsigned int off; -} TfwPool; - -#define TFW_POOL_CHUNK_SZ(p) (PAGE_SIZE << (p)->order) -#define TFW_POOL_CHUNK_BASE(c) ((unsigned long)(c) & PAGE_MASK) -#define TFW_POOL_CHUNK_END(p) (TFW_POOL_CHUNK_BASE((p)->curr) + (p)->off) -#define TFW_POOL_ALIGN_SZ(n) (((n) + 7) & ~7UL) -#define TFW_POOL_HEAD_OFF (TFW_POOL_ALIGN_SZ(sizeof(TfwPool)) \ - + TFW_POOL_ALIGN_SZ(sizeof(TfwPoolChunk))) -#define TFW_POOL_PGCACHE_SZ 256 - -static unsigned int pg_next; -static unsigned long pg_cache[TFW_POOL_PGCACHE_SZ]; - -static unsigned long -tfw_pool_alloc_pages(unsigned int order) -{ - if (likely(pg_next && !order)) - return pg_cache[--pg_next]; - return __get_free_pages(GFP_ATOMIC, order); -} - -static void -tfw_pool_free_pages(unsigned long addr, unsigned int order) -{ - if (likely(pg_next < TFW_POOL_PGCACHE_SZ && !order)) { - pg_cache[pg_next++] = addr; - } else { - free_pages(addr, order); - } -} - -TfwPool * -__tfw_pool_new(size_t n) -{ - TfwPool *p; - TfwPoolChunk *c; - unsigned int order; - - order = get_order(TFW_POOL_ALIGN_SZ(n) + TFW_POOL_HEAD_OFF); - - c = (TfwPoolChunk *)tfw_pool_alloc_pages(order); - if (unlikely(!c)) - return NULL; - - p = (TfwPool *)((char *)c + TFW_POOL_ALIGN_SZ(sizeof(*c))); - c->next = NULL; - - p->order = order; - p->off = TFW_POOL_HEAD_OFF; - p->curr = c; - - return p; -} - -void * -tfw_pool_alloc(TfwPool *p, size_t n) -{ - void *a; - - n = TFW_POOL_ALIGN_SZ(n); - - if (unlikely(p->off + n > TFW_POOL_CHUNK_SZ(p))) { - TfwPoolChunk *c, *curr = p->curr; - unsigned int off = TFW_POOL_ALIGN_SZ(sizeof(TfwPoolChunk)) + n; - unsigned int order = get_order(off); - - c = (TfwPoolChunk *)tfw_pool_alloc_pages(order); - if (!c) - return NULL; - c->next = curr; - - curr->order = p->order; - curr->off = p->off; - - p->order = order; - p->off = off; - p->curr = c; - - return (void *)TFW_POOL_ALIGN_SZ((unsigned long)(c + 1)); - } - - a = (char *)TFW_POOL_CHUNK_END(p); - p->off += n; - - return a; -} - -void -tfw_pool_free(TfwPool *p, void *ptr, size_t n) -{ - n = TFW_POOL_ALIGN_SZ(n); - - /* Stack-like usage is expected. */ - if (unlikely((char *)ptr + n != (char *)TFW_POOL_CHUNK_END(p))) - return; - - p->off -= n; - - /* Free empty chunk which doesn't contain the pool header. */ - if (unlikely(p->off == TFW_POOL_ALIGN_SZ(sizeof(TfwPoolChunk)))) { - TfwPoolChunk *next = p->curr->next; - tfw_pool_free_pages(TFW_POOL_CHUNK_BASE(p->curr), p->order); - p->curr = next; - p->order = next->order; - p->off = next->off; - } -} - -void -tfw_pool_destroy(TfwPool *p) -{ - TfwPoolChunk *c, *next; - - for (c = p->curr; c; c = next) { - next = c->next; - tfw_pool_free_pages(TFW_POOL_CHUNK_BASE(c), c->order); - } -} - -template -void -benchmark_tfw_pool() -{ - TfwPool *p = __tfw_pool_new(0); - assert(p); - - benchmark(std::move(T() + "tfw_pool"), [=]() { - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = (T *)tfw_pool_alloc(p, sizeof(T)); - touch_obj(o); - } - }); - - tfw_pool_destroy(p); -} - -template -void -benchmark_tfw_pool_free() -{ - TfwPool *p = __tfw_pool_new(0); - assert(p); - - benchmark(std::move(T() + "tfw_pool w/ free"), [&]() { - for (size_t i = 0; i < N * sizeof(Small) / sizeof(T); ++i) { - T *o = (T *)tfw_pool_alloc(p, sizeof(T)); - touch_obj(o); - if (__builtin_expect(!(i & 3), 0)) - tfw_pool_free(p, o, sizeof(T)); - } - }); - - tfw_pool_destroy(p); -} - -void -benchmark_tfw_pool_mix_free() -{ - TfwPool *p = __tfw_pool_new(0); - assert(p); - - benchmark(std::move(std::string("tfw_pool w/ free (Mix)")), [=]() { - for (size_t i = 0; i < N; ++i) { - if (__builtin_expect(!(i & 0xfff), 0)) { - Huge *o; - o = (Huge *)tfw_pool_alloc(p, sizeof(*o)); - touch_obj(o); - if (!(i & 1)) - tfw_pool_free(p, o, sizeof(*o)); - } - else if (__builtin_expect(!(i & 3), 0)) { - Big *o = (Big *)tfw_pool_alloc(p, sizeof(*o)); - touch_obj(o); - if (!(i & 1)) - tfw_pool_free(p, o, sizeof(*o)); - } - else { - Small *o; - o = (Small *)tfw_pool_alloc(p, sizeof(*o)); - touch_obj(o); - } - } - }); - - tfw_pool_destroy(p); -} - -void -benchmark_tfw_pool_create_and_destroy() -{ - benchmark(std::move(std::string("tfw_pool cr. & destr.")), []() { - for (size_t i = 0; i < N / 100; ++i) { - TfwPool *p = __tfw_pool_new(0); - for (size_t j = 0; j < 100; ++j) { - if (__builtin_expect(!(i & 3), 0)) { - Big *o; - o = (Big *)tfw_pool_alloc(p, - sizeof(*o)); - touch_obj(o); - } else { - Small *o; - o = (Small *)tfw_pool_alloc(p, - sizeof(*o)); - touch_obj(o); - } - } - tfw_pool_destroy(p); - } - }); -} - -/**************************************************************************/ -/* Adding M*LIB mempool */ -/**************************************************************************/ - -#include "m-mempool.h" - -MEMPOOL_DEF(mempool_small, Small) -MEMPOOL_DEF(mempool_big, Big) -MEMPOOL_DEF(mempool_huge, Huge) - -void -benchmark_mempool_small() -{ - mempool_small_t p; - mempool_small_init (p); - mempool_small_t *ptr = &p; // C++ lambda ! - - benchmark(std::move(Small() + "M*LIB mempool"), [=]() { - for (size_t i = 0; i < N * sizeof(Small) / sizeof(Small); ++i) { - Small *o = mempool_small_alloc(*ptr); - touch_obj(o); - } - }); - - mempool_small_clear(p); -} - -void -benchmark_mempool_big() -{ - mempool_big_t p; - mempool_big_init (p); - mempool_big_t *ptr = &p; // C++ lambda ! - - benchmark(std::move(Big() + "M*LIB mempool"), [=]() { - for (size_t i = 0; i < N * sizeof(Small) / sizeof(Big); ++i) { - Big *o = mempool_big_alloc(*ptr); - touch_obj(o); - } - }); - - mempool_big_clear(p); -} - -void -benchmark_mempool_mix_free() -{ - mempool_small_t s, *ptr_s = &s; - mempool_big_t b, *ptr_b = &b; - mempool_huge_t h, *ptr_h = &h; - - mempool_small_init (s); - mempool_big_init (b); - mempool_huge_init (h); - - benchmark(std::move(std::string("M*LIB mempool w/ free (Mix)")), [=]() { - for (size_t i = 0; i < N; ++i) { - if (__builtin_expect(!(i & 0xfff), 0)) { - Huge *o = mempool_huge_alloc (*ptr_h); - touch_obj(o); - if (!(i & 1)) - mempool_huge_free (*ptr_h, o); - } - else if (__builtin_expect(!(i & 3), 0)) { - Big *o = mempool_big_alloc(*ptr_b); - touch_obj(o); - if (!(i & 1)) - mempool_big_free (*ptr_b, o); - } - else { - Small *o = mempool_small_alloc (*ptr_s); - touch_obj(o); - if (!(i & 1)) - mempool_small_free (*ptr_s, o); - } - } - }); - - mempool_small_clear (s); - mempool_big_clear (b); - mempool_huge_clear (h); -} - -/* - * ------------------------------------------------------------------------ - * Main part of the benchmark - * ------------------------------------------------------------------------ - */ -int -main() -{ - std::cout << std::setw(35) << std::right << "small object size: " - << sizeof(Small) << std::endl; - std::cout << std::setw(35) << std::right << "big object size: " - << sizeof(Big) << std::endl; - std::cout << std::setw(35) << std::right << "huge object size: " - << sizeof(Huge) << "\n" << std::endl; - - // Warm up malloc(). - static const size_t n = N * sizeof(Big); - void *p = malloc(n); - assert(p); - memset(p, 0, n); - free(p); - - benchmark_mallocfree(); - benchmark_mallocfree_free(); - benchmark_mallocfree(); - benchmark_mallocfree_free(); - std::cout << std::endl; - -#ifdef USE_GLIB - benchmark_glib_slices(); - benchmark_glib_slices_free(); - benchmark_glib_slices(); - benchmark_glib_slices_free(); - std::cout << std::endl; -#endif - -#ifdef USE_BOOST - benchmark_boost_pool(); - benchmark_boost_pool_free(); - benchmark_boost_pool(); - benchmark_boost_pool_free(); - benchmark_boost_pool_create_and_destroy(); - std::cout << std::endl; -#endif - - benchmark_ngx_pool(); - benchmark_ngx_pool(); - benchmark_ngx_pool_mix_free(); - benchmark_ngx_pool_create_and_destroy(); - std::cout << std::endl; - - benchmark_mempool_small(); - benchmark_mempool_big(); - benchmark_mempool_mix_free(); - std::cout << std::endl; - - benchmark_tfw_pool(); - benchmark_tfw_pool_free(); - benchmark_tfw_pool(); - benchmark_tfw_pool_free(); - benchmark_tfw_pool_mix_free(); - benchmark_tfw_pool_create_and_destroy(); - - return 0; -} diff --git a/bench/udb/Makefile b/bench/udb/Makefile deleted file mode 100644 index 8ec3614d..00000000 --- a/bench/udb/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -CC= gcc -CXX= g++ -CFLAGS= -g -Wall -O2 -fomit-frame-pointer -march=native -lm -include stddef.h -CXXFLAGS= $(CFLAGS) -LDFLAGS= -OBJS= -LIBS= -lm - -all: run - -benchmarks: - git clone https://github.com/attractivechaos/benchmarks.git - -build: benchmarks - mkdir -p benchmarks/udb/mlib - cp test-mlib.c benchmarks/udb/mlib/test.c - cp Makefile-mlib benchmarks/udb/mlib/Makefile - mkdir -p benchmarks/udb/mlib-oa - cp test-mlib-oa.c benchmarks/udb/mlib-oa/test.c - cp Makefile-mlib benchmarks/udb/mlib-oa/Makefile - touch build - -all-recur: build - cd benchmarks/udb; \ - wdir=`pwd`; \ - list_c=`find . -name 'test.c'`; \ - list_cc=`find . -name 'test.cc'`; \ - for t in $$list_c $$list_cc ; do \ - subdir=`dirname $$t`; \ - cd $$subdir; \ - $(MAKE) CC="$(CC)" CXX="$(CXX)" DFLAGS="$(DFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" || exit 1; \ - cd $$wdir; \ - done; - -run: all-recur - @cd benchmarks/udb; \ - echo ; echo "LIBRARY | INT TIME | STR TIME" ; \ - for i in `find . -name 'test'` ; do \ - printf "%s|" `dirname $$i|sed -e 's+./++g'`; \ - $$i -is | awk ' \ - /\[int data\] # element/ { nbInt= $$5 } \ - /\[int data\] CPU time/ {timeInt= $$5 } \ - /\[str data\] # element/ { nbStr= $$5 } \ - /\[str data\] CPU time/ {timeStr= $$5 } \ - END { \ - if (nbInt != 624444) timeInt="BRK" ; \ - if (nbStr != 624444) timeStr="BRK" ; \ - print timeInt,"|" ,timeStr \ - }' ; \ - done - -clean: - rm -rf benchmarks build diff --git a/bench/udb/Makefile-mlib b/bench/udb/Makefile-mlib deleted file mode 100644 index 8c359828..00000000 --- a/bench/udb/Makefile-mlib +++ /dev/null @@ -1,22 +0,0 @@ -CC= gcc -CFLAGS= -g -Wall -O2 -march=native -OBJS= ../benchmark/benchmark.o ../runit/runlib.o test.o -DFLAGS= -INCLUDES= -I../benchmark -I../runit -I../../../../.. -LIBS= - -.SUFFIXES:.c .o - -.c.o: - $(CC) -std=gnu11 -DNDEBUG -c $(INCLUDES) $(CFLAGS) $(DFLAGS) $< -o $@ - -all:test - -test:$(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) - -cleanlocal: - rm -f *.o a.out *~ test - -clean:cleanlocal - diff --git a/bench/udb/test-mlib-oa.c b/bench/udb/test-mlib-oa.c deleted file mode 100644 index ba559be7..00000000 --- a/bench/udb/test-mlib-oa.c +++ /dev/null @@ -1,73 +0,0 @@ -#include - -#include "benchmark.h" -#include "m-dict.h" -#include "m-mempool.h" - -static inline bool oor_equal_p(int k, unsigned char n) -{ - return k == (int)-n - 1; -} - -static inline void oor_set(int *k, unsigned char n) -{ - *k = (int)-n - 1; -} - -DICT_OA_DEF2(dict_int, - int, M_OPEXTEND(M_DEFAULT_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)), - int, M_DEFAULT_OPLIST) - -static const char *const oor[2] = { "EMPTY", "DELETED" }; - -static inline bool str_oor_equal_p(const char *k, unsigned char n) -{ -return k == oor[n]; -} - -static inline void str_oor_set(const char * *k, unsigned char n) -{ -*k = oor[n]; -} - -DICT_OA_DEF2(dict_str, const char *, - M_OPEXTEND (M_CSTR_OPLIST, OOR_EQUAL(str_oor_equal_p), OOR_SET(str_oor_set M_IPTR)), - int, M_DEFAULT_OPLIST) - - -int test_int(int N, const unsigned *data) -{ - int ret; - M_LET(h, DICT_OPLIST(dict_int)) { - for (int i = 0; i < N; ++i) { - if (dict_int_get (h, data[i]) == NULL) { - dict_int_set_at (h, data[i], i); - } else { - dict_int_erase(h, data[i]); - } - } - ret = (int)dict_int_size(h); - } - return ret; -} - -int test_str(int N, char * const *data) -{ - int ret; - M_LET(h, DICT_OPLIST(dict_str)) { - for (int i = 0; i < N; ++i) { - if (dict_str_get (h, data[i]) == NULL) { - dict_str_set_at (h, data[i], i); - } else { - dict_str_erase(h, data[i]); - } - } - ret = (int)dict_str_size(h); - } - return ret; -} - -int main(int argc, char *argv[]) -{ - return udb_benchmark(argc, argv, test_int, test_str); -} diff --git a/bench/udb/test-mlib.c b/bench/udb/test-mlib.c deleted file mode 100644 index 4143f5a3..00000000 --- a/bench/udb/test-mlib.c +++ /dev/null @@ -1,53 +0,0 @@ -#include - -#include "benchmark.h" -#include "m-dict.h" -#include "m-mempool.h" - -DICT_STOREHASH_DEF2(dict_int, - int, M_OPEXTEND(M_DEFAULT_OPLIST, MEMPOOL(mpool_int), MEMPOOL_LINKAGE(static)), - int, M_DEFAULT_OPLIST) -DICT_STOREHASH_DEF2(dict_str, - const char *, M_OPEXTEND (M_CSTR_OPLIST, MEMPOOL(mpool_str), MEMPOOL_LINKAGE(static)), - int, M_DEFAULT_OPLIST) - -int test_int(int N, const unsigned *data) -{ - int ret; - dict_int_list_pair_mempool_init(mpool_int); - M_LET(h, DICT_OPLIST(dict_int)) { - for (int i = 0; i < N; ++i) { - if (dict_int_get (h, data[i]) == NULL) { - dict_int_set_at (h, data[i], i); - } else { - dict_int_erase(h, data[i]); - } - } - ret = (int)dict_int_size(h); - } - dict_int_list_pair_mempool_clear(mpool_int); - return ret; -} - -int test_str(int N, char * const *data) -{ - int ret; - dict_str_list_pair_mempool_init(mpool_str); - M_LET(h, DICT_OPLIST(dict_str)) { - for (int i = 0; i < N; ++i) { - if (dict_str_get (h, data[i]) == NULL) { - dict_str_set_at (h, data[i], i); - } else { - dict_str_erase(h, data[i]); - } - } - ret = (int)dict_str_size(h); - } - dict_str_list_pair_mempool_clear(mpool_str); - return ret; -} - -int main(int argc, char *argv[]) -{ - return udb_benchmark(argc, argv, test_int, test_str); -} diff --git a/bench/udb2/Makefile b/bench/udb2/Makefile deleted file mode 100644 index ad74abb0..00000000 --- a/bench/udb2/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -CC= gcc -CXX= g++ -CFLAGS= -g -Wall -O2 -fomit-frame-pointer -march=native -lm -include stddef.h -CXXFLAGS= $(CFLAGS) -LDFLAGS= -OBJS= -LIBS= - -all: run - -udb2: - git clone https://github.com/attractivechaos/udb2.git - -build: udb2 - mkdir -p udb2/mlib - cp test-mlib.c udb2/mlib/test.c - cp Makefile-mlib udb2/mlib/Makefile - touch build - -all-recur: build - cd udb2/stb && make CC="gcc -lm" - cd udb2 && for dir in `ls | egrep -v '^(Makefile|common.c|_)'`; do cd $$dir && make && cd -; done - -run: all-recur - @cd udb2; \ - echo ; echo RUNNING BENCH ; echo ; \ - for i in `find . -name 'run-test'` ; do \ - echo ; echo `dirname $$i|sed -e 's+./++g'`; \ - $$i ; \ - done - -clean: - rm -rf udb2 build *~ diff --git a/bench/udb2/Makefile-mlib b/bench/udb2/Makefile-mlib deleted file mode 100644 index 9ac82565..00000000 --- a/bench/udb2/Makefile-mlib +++ /dev/null @@ -1,8 +0,0 @@ -all:run-test - -run-test:test.c ../common.c - $(CC) -std=gnu99 -O2 -Wall -I../../../.. $< -o $@ - -clean: - rm -f run-test* *~ - rm -rf mlib diff --git a/bench/udb2/test-mlib.c b/bench/udb2/test-mlib.c deleted file mode 100644 index e6131681..00000000 --- a/bench/udb2/test-mlib.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "../common.c" -#define M_USE_DICT_OA_PROBING(s) 1 -#include "m-dict.h" - -static inline bool oor_equal_p(unsigned int k, unsigned char n) -{ - return k == (unsigned int)n; -} -static inline void oor_set(unsigned int *k, unsigned char n) -{ - *k = (unsigned int)n; -} - -DICT_OA_DEF2(dict_oa_uint, - unsigned int, M_OPEXTEND(M_DEFAULT_OPLIST, HASH(hash_fn), OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)), - unsigned int, M_DEFAULT_OPLIST) - -uint32_t test_int(uint32_t n, uint32_t x0) -{ - uint32_t i, x, z = 0; - dict_oa_uint_t h; - dict_oa_uint_init(h); - for (i = 0, x = x0; i < n; ++i) { - x = hash32(x); - unsigned int key = get_key(n, x); - unsigned int *ptr = dict_oa_uint_get_at(h, key); - (*ptr)++; - z += *ptr; - } - fprintf(stderr, "# unique keys: %d; checksum: %u\n", (int) dict_oa_uint_size(h), z); - z = dict_oa_uint_size(h); - dict_oa_uint_clear(h); - return z; -}