From 23de0a917954b1227ff5826ca02c113dd23dfc4d Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Fri, 10 May 2024 23:58:35 -0500 Subject: [PATCH] [ox/std] Add some functions for comparing HashMap and SmallMap (synced from 09d840cfd03b14d3fe6b174cd5d98c8b800cde3a) --- src/ox/std/test/CMakeLists.txt | 4 +- src/ox/std/test/tests.cpp | 156 ++++++++++++++++++++++++++++++++- 2 files changed, 155 insertions(+), 5 deletions(-) diff --git a/src/ox/std/test/CMakeLists.txt b/src/ox/std/test/CMakeLists.txt index d0c7da232..9c395b9c2 100644 --- a/src/ox/std/test/CMakeLists.txt +++ b/src/ox/std/test/CMakeLists.txt @@ -12,8 +12,10 @@ add_test("[ox/std] ox_memcmp HIJKLMN != ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTOR add_test("[ox/std] ox_memcmp ABCDEFG == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFG == ABCDEFG") add_test("[ox/std] ox_memcmp ABCDEFGHI == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFGHI == ABCDEFG") add_test("[ox/std] itoa" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "itoa") -add_test("[ox/std] BString" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "BString") +add_test("[ox/std] IString" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "IString") add_test("[ox/std] String" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "String") +add_test("[ox/std] SmallMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap") +add_test("[ox/std] SmallMap2" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap2") add_test("[ox/std] Vector" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Vector") add_test("[ox/std] HashMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "HashMap") add_test("[ox/std] HeapMgr" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest malloc) diff --git a/src/ox/std/test/tests.cpp b/src/ox/std/test/tests.cpp index 834540915..698088143 100644 --- a/src/ox/std/test/tests.cpp +++ b/src/ox/std/test/tests.cpp @@ -6,13 +6,111 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#include "ox/std/def.hpp" +#if __has_include() +#include +#endif + +#include #undef NDEBUG #include #include #include +[[nodiscard]] +static uint64_t nowMs() { +#if __has_include() + using namespace std::chrono; + return static_cast( + duration_cast( + system_clock::now().time_since_epoch()).count()); +#else + return 0; +#endif +} + +template> +uint64_t timeMapStrToUuid(int elemCnt, int lookups, uint64_t seed = 4321) noexcept { + ox::UUID::seedGenerator({1234, seed}); + Map map; + // setup test map + for (int i = 0; i < elemCnt; ++i) { + auto const uuid = ox::UUID::generate().unwrap(); + map[uuid.toString()] = uuid; + } + auto const keys = map.keys(); + ox::Random rand; + // start + auto const startTime = nowMs(); + for (int i = 0; i < lookups; ++i) { + auto const&k = keys[rand.gen() % keys.size()]; + map[k]; + } + return nowMs() - startTime; +} + +template> +uint64_t timeMapUuidToStr(int elemCnt, int lookups, uint64_t seed = 4321) noexcept { + ox::UUID::seedGenerator({1234, seed}); + Map map; + // setup test map + for (int i = 0; i < elemCnt; ++i) { + auto const uuid = ox::UUID::generate().unwrap(); + map[uuid] = uuid.toString(); + } + auto const keys = map.keys(); + ox::Random rand; + // start + auto const startTime = nowMs(); + for (int i = 0; i < lookups; ++i) { + auto const&k = keys[rand.gen() % keys.size()]; + oxExpect(map[k], k.toString()); + } + return nowMs() - startTime; +} + +static ox::Error compareMaps(int lookupCnt = 1'000'000) { + auto const seed = nowMs(); + uint64_t hashTime{}; + uint64_t smallTime{}; + int elemCnt = 1; + oxOut("UUIDStr to UUID:\n\n"); + while (hashTime >= smallTime) { + smallTime = timeMapStrToUuid>(elemCnt, lookupCnt, seed); + hashTime = timeMapStrToUuid>(elemCnt, lookupCnt, seed); + oxOutf( + "UUIDStr to UUID: elemCnt: {}, lookupCnt: {} - hash map time: {}ms, small map time: {}ms\n", + elemCnt, lookupCnt, hashTime, smallTime); + ++elemCnt; + } + oxOut("\n\nString to UUID:\n\n"); + hashTime = 0; + smallTime = 0; + elemCnt = 1; + while (hashTime >= smallTime) { + smallTime = timeMapStrToUuid>(elemCnt, lookupCnt, seed); + hashTime = timeMapStrToUuid>(elemCnt, lookupCnt, seed); + oxOutf( + "String to UUID: elemCnt: {}, lookupCnt: {} - hash map time: {}ms, small map time: {}ms\n", + elemCnt, lookupCnt, hashTime, smallTime); + ++elemCnt; + } + oxOut("\n\nUUID to UUIDStr:\n\n"); + hashTime = 0; + smallTime = 0; + elemCnt = 1; + while (hashTime >= smallTime) { + smallTime = timeMapUuidToStr>(elemCnt, lookupCnt, seed); + hashTime = timeMapUuidToStr>(elemCnt, lookupCnt, seed); + oxOutf( + "UUID to UUIDStr: elemCnt: {}, lookupCnt: {} - hash map time: {}ms, small map time: {}ms\n", + elemCnt, lookupCnt, hashTime, smallTime); + ++elemCnt; + } + oxOut("\n"); + return {}; +} + static std::map tests = { { "malloc", @@ -23,6 +121,8 @@ static std::map tests = { auto a2 = static_cast(ox::heapmgr::malloc(5)); oxAssert(a1 >= buff.front().unwrap() && a1 < buff.back().unwrap(), "malloc is broken"); oxAssert(a2 >= buff.front().unwrap() && a2 < buff.back().unwrap() && a2 > a1 + 5, "malloc is broken"); + ox::heapmgr::free(a1); + ox::heapmgr::free(a2); return OxError(0); } }, @@ -67,14 +167,14 @@ static std::map tests = { } }, { - "BString", + "IString", []() { ox::IString<5> s; oxReturnError(s.append("A")); oxReturnError(s.append("B")); oxReturnError(s.append("9")); oxReturnError(s.append("C")); - oxAssert(s == "AB9C", "BString append broken"); + oxAssert(s == "AB9C", "IString append broken"); s = "asdf"; oxAssert(s == "asdf", "String assign broken"); oxAssert(s != "aoeu", "String assign broken"); @@ -134,10 +234,38 @@ static std::map tests = { return OxError(0); } }, + { + "SmallMap", + [] { + ox::SmallMap map; + map["asdf"] = "aoeu"; + oxExpect(map["asdf"], "aoeu"); + oxExpect(map.size(), 1u); + oxExpect(map["aoeu"], ""); + oxExpect(map.size(), 2u); + return OxError(0); + } + }, + { + "SmallMap2", + [] { + ox::SmallMap si; + si["asdf"] = 42; + si["aoeu"] = 100; + oxAssert(si["asdf"] == 42, "asdf != 42"); + oxAssert(si["aoeu"] == 100, "aoeu != 100"); + ox::SmallMap ii; + ii[4] = 42; + ii[5] = 100; + oxAssert(ii[4] == 42, "4 != 42"); + oxAssert(ii[5] == 100, "5 != 100"); + return OxError(0); + } + }, { "HashMap", [] { - ox::HashMap si; + ox::HashMap si; si["asdf"] = 42; si["aoeu"] = 100; oxAssert(si["asdf"] == 42, "asdf != 42"); @@ -150,6 +278,26 @@ static std::map tests = { return OxError(0); } }, + { + "TimeSmallMapMillion", + [] { + timeMapStrToUuid>(1'000, 1'000'000); + return ox::Error{}; + } + }, + { + "TimeHashMapMillion", + [] { + timeMapStrToUuid>(1'000, 1'000'000); + return ox::Error{}; + } + }, + { + "CompareMaps", + [] { + return compareMaps(); + } + }, { "Serialize-Int", [] {