#include #include #include // for Rng, doNotOptimizeAway, Bench #include #include TEST_CASE("tuple_hash") { auto m = ankerl::unordered_dense::map, int>(); auto pair_hash = ankerl::unordered_dense::hash>{}; REQUIRE(pair_hash(std::pair{1, "a"}) != pair_hash(std::pair{1, "b"})); m.try_emplace({1, "a"}, 23); m.try_emplace({1, "b"}, 42); REQUIRE(m.size() == 2U); } TEST_CASE("good_tuple_hash") { auto hashes = ankerl::unordered_dense::set(); auto t = std::tuple(); for (size_t i = 0; i < 256 * 256; ++i) { std::get<0>(t) = static_cast(i); std::get<2>(t) = static_cast(i / 256); hashes.emplace(ankerl::unordered_dense::hash{}(t)); } REQUIRE(hashes.size() == 256 * 256); } TEST_CASE("tuple_hash_with_stringview") { using T = std::tuple; auto t = T(); std::get<0>(t) = 1; auto str = std::string("hello"); std::get<1>(t) = str; auto h1 = ankerl::unordered_dense::hash{}(t); str = "world"; REQUIRE(std::get<1>(t) == std::string{"world"}); auto h2 = ankerl::unordered_dense::hash{}(t); REQUIRE(h1 != h2); } // #include TEST_CASE("bench_tuple_hash" * doctest::test_suite("bench") * doctest::skip()) { using T = std::tuple; auto vecs = std::vector(100); auto rng = ankerl::nanobench::Rng(123); for (auto& v : vecs) { std::get<0>(v) = static_cast(rng()); std::get<1>(v) = static_cast(rng()); std::get<2>(v) = static_cast(rng()); std::get<3>(v) = static_cast(rng()); } uint64_t h = 0; ankerl::nanobench::Bench().batch(vecs.size()).run("ankerl hash", [&] { for (auto const& v : vecs) { h += ankerl::unordered_dense::hash{}(v); // h += absl::Hash{}(v); } }); ankerl::nanobench::doNotOptimizeAway(h); }