From ca1f2fb3d1ac280b8eb0271d936fcd024c58124d Mon Sep 17 00:00:00 2001 From: Neil Henning Date: Wed, 22 Mar 2023 21:42:30 +0000 Subject: [PATCH] Merge benchmarks with tests so that they are always compiled and ran. --- .github/workflows/cmake.yml | 2 +- .github/workflows/sanitizers.yaml | 2 +- appveyor.yml | 2 +- bench/CMakeLists.txt | 59 -------- bench/main.c | 232 ------------------------------ bench/sse42.c | 229 ----------------------------- hashmap.h | 5 +- test/main.c | 26 +++- test/test.c | 2 + test/test.cpp | 2 + test/test.inc | 194 ++++++++++++++++++++++++- test/test11.cpp | 2 + test/test_sse42.c | 2 + {bench => test}/ubench.h | 7 + test/utest.h | 4 + 15 files changed, 243 insertions(+), 527 deletions(-) delete mode 100644 bench/CMakeLists.txt delete mode 100644 bench/main.c delete mode 100644 bench/sse42.c rename {bench => test}/ubench.h (99%) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 7c772cc..d1742bb 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -63,4 +63,4 @@ jobs: - name: Test working-directory: ${{github.workspace}}/build shell: bash - run: if [ "${{ matrix.os }}" == "windows-latest" ]; then cd ${{ matrix.type }}; fi; ./hashmap_test + run: if [ "${{ matrix.os }}" == "windows-latest" ]; then cd ${{ matrix.type }}; fi; ./hashmap_test test diff --git a/.github/workflows/sanitizers.yaml b/.github/workflows/sanitizers.yaml index 14c988a..6e1234f 100644 --- a/.github/workflows/sanitizers.yaml +++ b/.github/workflows/sanitizers.yaml @@ -47,4 +47,4 @@ jobs: - name: Test working-directory: ${{github.workspace}}/build shell: bash - run: ./hashmap_test + run: ./hashmap_test --confidence=100 diff --git a/appveyor.yml b/appveyor.yml index 851d359..6c55bbe 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -46,4 +46,4 @@ build_script: - copy %CONFIGURATION%\hashmap_test.exe hashmap_test.exe test_script: - - hashmap_test.exe + - hashmap_test.exe test diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt deleted file mode 100644 index f16ea8e..0000000 --- a/bench/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -# This is free and unencumbered software released into the public domain. -# -# Anyone is free to copy, modify, publish, use, compile, sell, or -# distribute this software, either in source code form or as a compiled -# binary, for any purpose, commercial or non-commercial, and by any -# means. -# -# In jurisdictions that recognize copyright laws, the author or authors -# of this software dedicate any and all copyright interest in the -# software to the public domain. We make this dedication for the benefit -# of the public at large and to the detriment of our heirs and -# successors. We intend this dedication to be an overt act of -# relinquishment in perpetuity of all present and future rights to this -# software under copyright law. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -# For more information, please refer to - -project(hashmap) -cmake_minimum_required(VERSION 3.1.3) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../) - -add_executable(hashmap_bench - ../hashmap.h - main.c - sse42.c -) - -if (NOT "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm64") - if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") - set_source_files_properties(sse42.c PROPERTIES - COMPILE_FLAGS "-Wall -Wextra -Werror -std=gnu89 -msse4.2" - ) - elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") - if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") - set_source_files_properties(sse42.c PROPERTIES - COMPILE_FLAGS "/Wall /WX /wd4514 /wd5045 /arch:AVX" - ) - else() - set_source_files_properties(sse42.c PROPERTIES - COMPILE_FLAGS "-Wall -Wextra -Weverything -Werror -std=gnu89 -msse4.2" - ) - endif() - elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") - set_source_files_properties(sse42.c PROPERTIES - COMPILE_FLAGS "/Wall /WX /wd4514 /wd5045 /arch:AVX" - ) - else() - message(WARNING "Unknown compiler '${CMAKE_C_COMPILER_ID}'!") - endif() -endif() diff --git a/bench/main.c b/bench/main.c deleted file mode 100644 index e7bbe5c..0000000 --- a/bench/main.c +++ /dev/null @@ -1,232 +0,0 @@ -// This is free and unencumbered software released into the public domain. -// -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. -// -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -// For more information, please refer to - -#include "ubench.h" -#include "hashmap.h" - -#if defined(HASHMAP_X86_SSE42) -#error Cannot be compiled with SSE 4.2 support! -#endif - -UBENCH(create, initial_size_1_kilobyte) { - struct hashmap_s hashmap; - hashmap_create(1024, &hashmap); - UBENCH_DO_NOTHING(&hashmap); - hashmap_destroy(&hashmap); -} - -struct put_small_keys { - char *keys; - unsigned key_len; -}; - -UBENCH_F_SETUP(put_small_keys) { - const unsigned max_keys = 1024 * 1024; - const unsigned key_len = 8; - char *const keys = malloc(max_keys * key_len); - unsigned i; - - for (i = 0; i < max_keys; i++) { - snprintf(keys + (i * key_len), key_len, "%08x", i); - } - - ubench_fixture->keys = keys; - ubench_fixture->key_len = key_len; -} - -UBENCH_F_TEARDOWN(put_small_keys) { free(ubench_fixture->keys); } - -UBENCH_F(put_small_keys, 1024) { - struct hashmap_s hashmap; - int i; - - hashmap_create(1, &hashmap); - - for (i = 0; i < 1024; i++) { - const unsigned offset = i * ubench_fixture->key_len; - hashmap_put(&hashmap, ubench_fixture->keys + offset, - ubench_fixture->key_len, 0); - } - - UBENCH_DO_NOTHING(&hashmap); - hashmap_destroy(&hashmap); -} - -UBENCH_F(put_small_keys, 1048576) { - struct hashmap_s hashmap; - int i; - - hashmap_create(1, &hashmap); - - for (i = 0; i < 1048576; i++) { - const unsigned offset = i * ubench_fixture->key_len; - hashmap_put(&hashmap, ubench_fixture->keys + offset, - ubench_fixture->key_len, 0); - } - - UBENCH_DO_NOTHING(&hashmap); - hashmap_destroy(&hashmap); -} - -struct put_large_keys { - char *keys; - unsigned key_len; -}; - -UBENCH_F_SETUP(put_large_keys) { - const unsigned max_keys = 1024 * 1024; - const unsigned key_len = 1024; - char *const keys = malloc(max_keys * key_len); - unsigned i; - - for (i = 0; i < max_keys; i++) { - snprintf(keys + (i * key_len), key_len, "%01024x", i); - } - - ubench_fixture->keys = keys; - ubench_fixture->key_len = key_len; -} - -UBENCH_F_TEARDOWN(put_large_keys) { free(ubench_fixture->keys); } - -UBENCH_F(put_large_keys, 1048576) { - struct hashmap_s hashmap; - int i; - - hashmap_create(1, &hashmap); - - for (i = 0; i < 1048576; i++) { - const unsigned offset = i * ubench_fixture->key_len; - hashmap_put(&hashmap, ubench_fixture->keys + offset, - ubench_fixture->key_len, 0); - } - - UBENCH_DO_NOTHING(&hashmap); - hashmap_destroy(&hashmap); -} - -struct get_small_keys { - char *keys; - unsigned key_len; - struct hashmap_s hashmap; -}; - -UBENCH_F_SETUP(get_small_keys) { - const unsigned max_keys = 1024 * 1024; - const unsigned key_len = 8; - char *const keys = malloc(max_keys * key_len); - unsigned i; - struct hashmap_s hashmap; - - for (i = 0; i < max_keys; i++) { - snprintf(keys + (i * key_len), key_len, "%08x", i); - } - hashmap_create(1, &hashmap); - - for (i = 0; i < max_keys; i++) { - const unsigned offset = i * key_len; - hashmap_put(&hashmap, keys + offset, key_len, 0); - } - - ubench_fixture->keys = keys; - ubench_fixture->key_len = key_len; - ubench_fixture->hashmap = hashmap; -} - -UBENCH_F_TEARDOWN(get_small_keys) { - hashmap_destroy(&ubench_fixture->hashmap); - free(ubench_fixture->keys); -} - -UBENCH_F(get_small_keys, small_missing_key) { - UBENCH_DO_NOTHING(hashmap_get(&ubench_fixture->hashmap, "a", strlen("a"))); -} - -UBENCH_F(get_small_keys, large_missing_key) { -#define DATA_SIZE (16 * 1024) - char data[DATA_SIZE]; - const unsigned data_size = DATA_SIZE; -#undef DATA_SIZE - unsigned i; - - for (i = 0; i < data_size; i++) { - data[i] = (char)i; - } - - UBENCH_DO_NOTHING(hashmap_get(&ubench_fixture->hashmap, data, data_size)); -} - -struct get_large_keys { - char *keys; - unsigned key_len; - struct hashmap_s hashmap; -}; - -UBENCH_F_SETUP(get_large_keys) { - const unsigned max_keys = 1024 * 1024; - const unsigned key_len = 1024; - char *const keys = malloc(max_keys * key_len); - unsigned i; - struct hashmap_s hashmap; - - for (i = 0; i < max_keys; i++) { - snprintf(keys + (i * key_len), key_len, "%01024x", i); - } - hashmap_create(1, &hashmap); - - for (i = 0; i < max_keys; i++) { - const unsigned offset = i * key_len; - hashmap_put(&hashmap, keys + offset, key_len, 0); - } - - ubench_fixture->keys = keys; - ubench_fixture->key_len = key_len; - ubench_fixture->hashmap = hashmap; -} - -UBENCH_F_TEARDOWN(get_large_keys) { - hashmap_destroy(&ubench_fixture->hashmap); - free(ubench_fixture->keys); -} - -UBENCH_F(get_large_keys, small_missing_key) { - UBENCH_DO_NOTHING(hashmap_get(&ubench_fixture->hashmap, "a", strlen("a"))); -} - -UBENCH_F(get_large_keys, large_missing_key) { -#define DATA_SIZE (16 * 1024) - char data[DATA_SIZE]; - const unsigned data_size = DATA_SIZE; -#undef DATA_SIZE - unsigned i; - - for (i = 0; i < data_size; i++) { - data[i] = (char)i; - } - - UBENCH_DO_NOTHING(hashmap_get(&ubench_fixture->hashmap, data, data_size)); -} - -UBENCH_MAIN() diff --git a/bench/sse42.c b/bench/sse42.c deleted file mode 100644 index f13919e..0000000 --- a/bench/sse42.c +++ /dev/null @@ -1,229 +0,0 @@ -// This is free and unencumbered software released into the public domain. -// -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. -// -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -// For more information, please refer to - -#include "ubench.h" -#include "hashmap.h" - -#if (defined(_MSC_VER) && defined(__AVX__)) || \ - (!defined(_MSC_VER) && defined(__SSE4_2__)) -UBENCH(create_sse42, initial_size_1_kilobyte) { - struct hashmap_s hashmap; - hashmap_create(1024, &hashmap); - UBENCH_DO_NOTHING(&hashmap); - hashmap_destroy(&hashmap); -} - -struct put_small_keys_sse42 { - char *keys; - unsigned key_len; -}; - -UBENCH_F_SETUP(put_small_keys_sse42) { - const unsigned max_keys = 1024 * 1024; - const unsigned key_len = 8; - char *const keys = malloc(max_keys * key_len); - unsigned i; - - for (i = 0; i < max_keys; i++) { - snprintf(keys + (i * key_len), key_len, "%08x", i); - } - - ubench_fixture->keys = keys; - ubench_fixture->key_len = key_len; -} - -UBENCH_F_TEARDOWN(put_small_keys_sse42) { free(ubench_fixture->keys); } - -UBENCH_F(put_small_keys_sse42, 1024) { - struct hashmap_s hashmap; - int i; - - hashmap_create(1, &hashmap); - - for (i = 0; i < 1024; i++) { - const unsigned offset = i * ubench_fixture->key_len; - hashmap_put(&hashmap, ubench_fixture->keys + offset, - ubench_fixture->key_len, 0); - } - - UBENCH_DO_NOTHING(&hashmap); - hashmap_destroy(&hashmap); -} - -UBENCH_F(put_small_keys_sse42, 1048576) { - struct hashmap_s hashmap; - int i; - - hashmap_create(1, &hashmap); - - for (i = 0; i < 1048576; i++) { - const unsigned offset = i * ubench_fixture->key_len; - hashmap_put(&hashmap, ubench_fixture->keys + offset, - ubench_fixture->key_len, 0); - } - - UBENCH_DO_NOTHING(&hashmap); - hashmap_destroy(&hashmap); -} - -struct put_large_keys_sse42 { - char *keys; - unsigned key_len; -}; - -UBENCH_F_SETUP(put_large_keys_sse42) { - const unsigned max_keys = 1024 * 1024; - const unsigned key_len = 1024; - char *const keys = malloc(max_keys * key_len); - unsigned i; - - for (i = 0; i < max_keys; i++) { - snprintf(keys + (i * key_len), key_len, "%01024x", i); - } - - ubench_fixture->keys = keys; - ubench_fixture->key_len = key_len; -} - -UBENCH_F_TEARDOWN(put_large_keys_sse42) { free(ubench_fixture->keys); } - -UBENCH_F(put_large_keys_sse42, 1048576) { - struct hashmap_s hashmap; - int i; - - hashmap_create(1, &hashmap); - - for (i = 0; i < 1048576; i++) { - const unsigned offset = i * ubench_fixture->key_len; - hashmap_put(&hashmap, ubench_fixture->keys + offset, - ubench_fixture->key_len, 0); - } - - UBENCH_DO_NOTHING(&hashmap); - hashmap_destroy(&hashmap); -} - -struct get_small_keys_sse42 { - char *keys; - unsigned key_len; - struct hashmap_s hashmap; -}; - -UBENCH_F_SETUP(get_small_keys_sse42) { - const unsigned max_keys = 1024 * 1024; - const unsigned key_len = 8; - char *const keys = malloc(max_keys * key_len); - unsigned i; - struct hashmap_s hashmap; - - for (i = 0; i < max_keys; i++) { - snprintf(keys + (i * key_len), key_len, "%08x", i); - } - hashmap_create(1, &hashmap); - - for (i = 0; i < max_keys; i++) { - const unsigned offset = i * key_len; - hashmap_put(&hashmap, keys + offset, key_len, 0); - } - - ubench_fixture->keys = keys; - ubench_fixture->key_len = key_len; - ubench_fixture->hashmap = hashmap; -} - -UBENCH_F_TEARDOWN(get_small_keys_sse42) { - hashmap_destroy(&ubench_fixture->hashmap); - free(ubench_fixture->keys); -} - -UBENCH_F(get_small_keys_sse42, small_missing_key) { - UBENCH_DO_NOTHING(hashmap_get(&ubench_fixture->hashmap, "a", (unsigned)strlen("a"))); -} - -UBENCH_F(get_small_keys_sse42, large_missing_key) { -#define DATA_SIZE (16 * 1024) - char data[DATA_SIZE]; - const unsigned data_size = DATA_SIZE; -#undef DATA_SIZE - unsigned i; - - for (i = 0; i < data_size; i++) { - data[i] = (char)i; - } - - UBENCH_DO_NOTHING(hashmap_get(&ubench_fixture->hashmap, data, data_size)); -} - -struct get_large_keys_sse42 { - char *keys; - unsigned key_len; - struct hashmap_s hashmap; -}; - -UBENCH_F_SETUP(get_large_keys_sse42) { - const unsigned max_keys = 1024 * 1024; - const unsigned key_len = 1024; - char *const keys = malloc(max_keys * key_len); - unsigned i; - struct hashmap_s hashmap; - - for (i = 0; i < max_keys; i++) { - snprintf(keys + (i * key_len), key_len, "%01024x", i); - } - hashmap_create(1, &hashmap); - - for (i = 0; i < max_keys; i++) { - const unsigned offset = i * key_len; - hashmap_put(&hashmap, keys + offset, key_len, 0); - } - - ubench_fixture->keys = keys; - ubench_fixture->key_len = key_len; - ubench_fixture->hashmap = hashmap; -} - -UBENCH_F_TEARDOWN(get_large_keys_sse42) { - hashmap_destroy(&ubench_fixture->hashmap); - free(ubench_fixture->keys); -} - -UBENCH_F(get_large_keys_sse42, small_missing_key) { - UBENCH_DO_NOTHING(hashmap_get(&ubench_fixture->hashmap, "a", (unsigned)strlen("a"))); -} - -UBENCH_F(get_large_keys_sse42, large_missing_key) { -#define DATA_SIZE (16 * 1024) - char data[DATA_SIZE]; - const unsigned data_size = DATA_SIZE; -#undef DATA_SIZE - unsigned i; - - for (i = 0; i < data_size; i++) { - data[i] = (char)i; - } - - UBENCH_DO_NOTHING(hashmap_get(&ubench_fixture->hashmap, data, data_size)); -} -#endif diff --git a/hashmap.h b/hashmap.h index b4aaf57..45a75ef 100644 --- a/hashmap.h +++ b/hashmap.h @@ -161,8 +161,9 @@ HASHMAP_WEAK int hashmap_create(const hashmap_uint32_t initial_capacity, /// /// The options members work as follows: /// - initial_capacity The initial capacity of the hashmap. -/// - hasher Which hashing function to use with the hashmap (by default the -// crc32 with Robert Jenkins' mix is used). +/// - hasher Which hashing function to use with the hashmap (by default a crc32 +/// hash is used). +/// - comparer Which key compare function to use (the default is memcmp). HASHMAP_WEAK int hashmap_create_ex(struct hashmap_create_options_s options, struct hashmap_s *const out_hashmap); diff --git a/test/main.c b/test/main.c index f6c50cc..f947065 100644 --- a/test/main.c +++ b/test/main.c @@ -24,5 +24,29 @@ // For more information, please refer to #include "utest.h" +#include "ubench.h" -UTEST_MAIN() +#include + +UTEST_STATE(); +UBENCH_STATE(); + +int main(const int argc, const char *const argv[]) { + int result; + + if (1 < argc) { + if (0 == strcmp(argv[1], "test")) { + return utest_main(argc, argv); + } else if (0 == strcmp(argv[1], "bench")) { + return ubench_main(argc, argv); + } + } + + result = utest_main(argc, argv); + + if (0 != result) { + return result; + } + + return ubench_main(argc, argv); +} diff --git a/test/test.c b/test/test.c index 5440670..12f7db1 100644 --- a/test/test.c +++ b/test/test.c @@ -1,6 +1,8 @@ #include "hashmap.h" #include "utest.h" +#include "ubench.h" #define MY_TEST_WRAPPER(name) UTEST(c, name) +#define MY_BENCH_WRAPPER(name) UBENCH_EX(c, name) #include "test.inc" diff --git a/test/test.cpp b/test/test.cpp index b345a57..05b7651 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,6 +1,8 @@ #include "hashmap.h" #include "utest.h" +#include "ubench.h" #define MY_TEST_WRAPPER(name) UTEST(cpp, name) +#define MY_BENCH_WRAPPER(name) UBENCH_EX(cpp, name) #include "test.inc" diff --git a/test/test.inc b/test/test.inc index 46f195a..1aab750 100644 --- a/test/test.inc +++ b/test/test.inc @@ -318,7 +318,7 @@ MY_TEST_WRAPPER(two_bytes) { ASSERT_EQ(0, hashmap_create(1, &hashmap)); for (i = 0; i < 16384; i++) { - ASSERT_EQ(0, hashmap_put(&hashmap, &data[i], 2, NULL)); + ASSERT_EQ(0, hashmap_put(&hashmap, &data[i], 2, HASHMAP_NULL)); } ASSERT_EQ(hashmap_num_entries(&hashmap), 16384u); @@ -327,3 +327,195 @@ MY_TEST_WRAPPER(two_bytes) { hashmap_destroy(&hashmap); free(data); } + +MY_BENCH_WRAPPER(put_16384_2_byte_keys) { + unsigned short *data; + int i; + struct hashmap_s hashmap; + + data = HASHMAP_PTR_CAST(unsigned short *, + malloc(sizeof(unsigned short) * 16384)); + + for (i = 0; i < 16384; i++) { + data[i] = HASHMAP_CAST(unsigned short, i); + } + + hashmap_create(1, &hashmap); + + UBENCH_DO_BENCHMARK() { + for (i = 0; i < 16384; i++) { + hashmap_put(&hashmap, &data[i], 2, HASHMAP_NULL); + } + } + + hashmap_destroy(&hashmap); + free(data); +} + +MY_BENCH_WRAPPER(get_16384_2_byte_keys) { + unsigned short *data; + int i; + struct hashmap_s hashmap; + + data = HASHMAP_PTR_CAST(unsigned short *, + malloc(sizeof(unsigned short) * 16384)); + + for (i = 0; i < 16384; i++) { + data[i] = HASHMAP_CAST(unsigned short, i); + } + + hashmap_create(1, &hashmap); + + for (i = 0; i < 16384; i++) { + hashmap_put(&hashmap, &data[i], 2, HASHMAP_NULL); + } + + UBENCH_DO_BENCHMARK() { + for (i = 0; i < 16384; i++) { + UBENCH_DO_NOTHING(hashmap_get(&hashmap, &data[i], 2)); + } + } + + hashmap_destroy(&hashmap); + free(data); +} + +MY_BENCH_WRAPPER(remove_16384_2_byte_keys) { + unsigned short *data; + int i; + struct hashmap_s hashmap; + + data = HASHMAP_PTR_CAST(unsigned short *, + malloc(sizeof(unsigned short) * 16384)); + + for (i = 0; i < 16384; i++) { + data[i] = HASHMAP_CAST(unsigned short, i); + } + + hashmap_create(1, &hashmap); + + for (i = 0; i < 16384; i++) { + hashmap_put(&hashmap, &data[i], 2, HASHMAP_NULL); + } + + UBENCH_DO_BENCHMARK() { + for (i = 0; i < 16384; i++) { + hashmap_remove(&hashmap, &data[i], 2); + } + } + + hashmap_destroy(&hashmap); + free(data); +} + +MY_BENCH_WRAPPER(put_4096_1024_byte_keys) { + unsigned char *data; + int i; + struct hashmap_s hashmap; + + data = HASHMAP_PTR_CAST(unsigned char *, malloc(16384 * 1024)); + memset(data, 0, 4096 * 1024); + + for (i = 0; i < 4096; i++) { + memcpy(&data[i * 1024 + (1024 - 4)], &i, sizeof(i)); + } + + hashmap_create(1, &hashmap); + + UBENCH_DO_BENCHMARK() { + for (i = 0; i < 4096; i++) { + hashmap_put(&hashmap, &data[i * 1024], 1024, HASHMAP_NULL); + } + } + + hashmap_destroy(&hashmap); + free(data); +} + +MY_BENCH_WRAPPER(get_4096_1024_byte_keys) { + unsigned char *data; + int i; + struct hashmap_s hashmap; + + data = HASHMAP_PTR_CAST(unsigned char *, malloc(16384 * 1024)); + memset(data, 0, 4096 * 1024); + + for (i = 0; i < 4096; i++) { + memcpy(&data[i * 1024 + (1024 - 4)], &i, sizeof(i)); + } + + hashmap_create(1, &hashmap); + + for (i = 0; i < 4096; i++) { + hashmap_put(&hashmap, &data[i * 1024], 1024, HASHMAP_NULL); + } + + UBENCH_DO_BENCHMARK() { + for (i = 0; i < 4096; i++) { + UBENCH_DO_NOTHING(hashmap_get(&hashmap, &data[i * 1024], 1024)); + } + } + + hashmap_destroy(&hashmap); + free(data); +} + +MY_BENCH_WRAPPER(remove_4096_1024_byte_keys) { + unsigned char *data; + int i; + struct hashmap_s hashmap; + + data = HASHMAP_PTR_CAST(unsigned char *, malloc(16384 * 1024)); + memset(data, 0, 4096 * 1024); + + for (i = 0; i < 4096; i++) { + memcpy(&data[i * 1024 + (1024 - 4)], &i, sizeof(i)); + } + + hashmap_create(1, &hashmap); + + for (i = 0; i < 4096; i++) { + hashmap_put(&hashmap, &data[i * 1024], 1024, HASHMAP_NULL); + } + + UBENCH_DO_BENCHMARK() { + for (i = 0; i < 4096; i++) { + hashmap_remove(&hashmap, &data[i * 1024], 1024); + } + } + + hashmap_destroy(&hashmap); + free(data); +} + +static int my_iterator(void *const context, void *const value) { + UBENCH_DO_NOTHING(context); + UBENCH_DO_NOTHING(value); + return 1; +} + +MY_BENCH_WRAPPER(iterate_4096_1024_byte_keys) { + unsigned char *data; + int i; + struct hashmap_s hashmap; + + data = HASHMAP_PTR_CAST(unsigned char *, malloc(16384 * 1024)); + memset(data, 0, 4096 * 1024); + + for (i = 0; i < 4096; i++) { + memcpy(&data[i * 1024 + (1024 - 4)], &i, sizeof(i)); + } + + hashmap_create(1, &hashmap); + + for (i = 0; i < 4096; i++) { + hashmap_put(&hashmap, &data[i * 1024], 1024, HASHMAP_NULL); + } + + UBENCH_DO_BENCHMARK() { + hashmap_iterate(&hashmap, &my_iterator, HASHMAP_NULL); + } + + hashmap_destroy(&hashmap); + free(data); +} diff --git a/test/test11.cpp b/test/test11.cpp index 3fbead5..226b902 100644 --- a/test/test11.cpp +++ b/test/test11.cpp @@ -1,6 +1,8 @@ #include "hashmap.h" #include "utest.h" +#include "ubench.h" #define MY_TEST_WRAPPER(name) UTEST(cpp11, name) +#define MY_BENCH_WRAPPER(name) UBENCH_EX(cpp11, name) #include "test.inc" diff --git a/test/test_sse42.c b/test/test_sse42.c index 99c1c34..b10146e 100644 --- a/test/test_sse42.c +++ b/test/test_sse42.c @@ -1,10 +1,12 @@ #include "hashmap.h" #include "utest.h" +#include "ubench.h" #if (defined(_MSC_VER) && defined(__AVX__)) || \ (!defined(_MSC_VER) && defined(__SSE4_2__)) #define MY_TEST_WRAPPER(name) UTEST(c_sse2, name) +#define MY_BENCH_WRAPPER(name) UBENCH_EX(c_sse2, name) #include "test.inc" diff --git a/bench/ubench.h b/test/ubench.h similarity index 99% rename from bench/ubench.h rename to test/ubench.h index 90f885a..a1ec945 100644 --- a/bench/ubench.h +++ b/test/ubench.h @@ -96,6 +96,8 @@ typedef uint64_t ubench_uint64_t; #endif #if defined(_MSC_VER) + +#if !defined(SHEREDOM_UTEST_H_INCLUDED) typedef union { struct { unsigned long LowPart; @@ -112,6 +114,11 @@ UBENCH_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceCounter( ubench_large_integer *); UBENCH_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceFrequency( ubench_large_integer *); + +#else +typedef utest_large_integer ubench_large_integer; +#endif + #elif defined(__linux__) /* diff --git a/test/utest.h b/test/utest.h index 021f366..5745471 100644 --- a/test/utest.h +++ b/test/utest.h @@ -119,6 +119,7 @@ typedef uint32_t utest_uint32_t; #pragma GCC diagnostic ignored "-Wunknown-pragmas" #endif +#if !defined(SHEREDOM_UBENCH_H_INCLUDED) // use old QueryPerformanceCounter definitions (not sure is this needed in some // edge cases or not) on Win7 with VS2015 these extern declaration cause "second // C linkage of overloaded function not allowed" error @@ -138,6 +139,9 @@ UTEST_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceCounter( utest_large_integer *); UTEST_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceFrequency( utest_large_integer *); +#else +typedef ubench_large_integer utest_large_integer; +#endif #if defined(__MINGW64__) || defined(__MINGW32__) #pragma GCC diagnostic pop