From 5458877f2c7787a75d7a00e7a799f5090f59b536 Mon Sep 17 00:00:00 2001 From: Marius Bancila Date: Thu, 23 Dec 2021 01:00:23 +0200 Subject: [PATCH] faster std::hash implementation --- include/uuid.h | 33 +++++++++++++++++++++++++++++++++ test/test_uuid.cpp | 4 ++++ 2 files changed, 37 insertions(+) diff --git a/include/uuid.h b/include/uuid.h index 0515d47..b8c4a49 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -526,6 +526,8 @@ namespace uuids template friend std::basic_string to_string(uuid const& id); + + friend std::hash; }; // -------------------------------------------------------------------------------------------------------------------------- @@ -922,8 +924,39 @@ namespace std result_type operator()(argument_type const &uuid) const { +#ifdef UUID_HASH_STRING_BASED std::hash hasher; return static_cast(hasher(uuids::to_string(uuid))); +#else + uint64_t l = + static_cast(uuid.data[0]) << 56 | + static_cast(uuid.data[1]) << 48 | + static_cast(uuid.data[2]) << 40 | + static_cast(uuid.data[3]) << 32 | + static_cast(uuid.data[4]) << 24 | + static_cast(uuid.data[5]) << 16 | + static_cast(uuid.data[6]) << 8 | + static_cast(uuid.data[7]); + uint64_t h = + static_cast(uuid.data[8]) << 56 | + static_cast(uuid.data[9]) << 48 | + static_cast(uuid.data[10]) << 40 | + static_cast(uuid.data[11]) << 32 | + static_cast(uuid.data[12]) << 24 | + static_cast(uuid.data[13]) << 16 | + static_cast(uuid.data[14]) << 8 | + static_cast(uuid.data[15]); + + if (sizeof(result_type) > 4) + { + return result_type(l ^ h); + } + else + { + uint64_t hash64 = l ^ h; + return result_type(uint32_t(hash64 >> 32) ^ uint32_t(hash64)); + } +#endif } }; } diff --git a/test/test_uuid.cpp b/test/test_uuid.cpp index 001a6ae..ea98eb1 100644 --- a/test/test_uuid.cpp +++ b/test/test_uuid.cpp @@ -525,7 +525,11 @@ TEST_CASE("Test hashing", "[ops]") auto h1 = std::hash{}; auto h2 = std::hash{}; +#ifdef UUID_HASH_STRING_BASED REQUIRE(h1(str) == h2(guid)); +#else + REQUIRE(h1(str) != h2(guid)); +#endif auto engine = uuids::uuid_random_generator::engine_type{}; seed_rng(engine);