[libcxx-commits] [libcxx] [libc++] Split std::hash benchmark out of std::unordered_set benchmark (PR #114448)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Oct 31 11:37:06 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

<details>
<summary>Changes</summary>

As a drive-by, remove unused functor inside the unordered_set benchmark. That benchmark isn't very exhaustive, but that can be addressed separately.

---
Full diff: https://github.com/llvm/llvm-project/pull/114448.diff


3 Files Affected:

- (modified) libcxx/test/benchmarks/CMakeLists.txt (+1) 
- (added) libcxx/test/benchmarks/hash.bench.cpp (+80) 
- (modified) libcxx/test/benchmarks/unordered_set_operations.bench.cpp (-37) 


``````````diff
diff --git a/libcxx/test/benchmarks/CMakeLists.txt b/libcxx/test/benchmarks/CMakeLists.txt
index b402af8d80dae8..5e829a639d39a5 100644
--- a/libcxx/test/benchmarks/CMakeLists.txt
+++ b/libcxx/test/benchmarks/CMakeLists.txt
@@ -157,6 +157,7 @@ set(BENCHMARK_TESTS
     formatter_float.bench.cpp
     formatter_int.bench.cpp
     function.bench.cpp
+    hash.bench.cpp
     join_view.bench.cpp
     lexicographical_compare_three_way.bench.cpp
     map.bench.cpp
diff --git a/libcxx/test/benchmarks/hash.bench.cpp b/libcxx/test/benchmarks/hash.bench.cpp
new file mode 100644
index 00000000000000..e0159874476293
--- /dev/null
+++ b/libcxx/test/benchmarks/hash.bench.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+#include <cstdint>
+#include <cstddef>
+#include <functional>
+
+#include "benchmark/benchmark.h"
+
+#include "GenerateInput.h"
+#include "test_macros.h"
+
+constexpr std::size_t TestNumInputs = 1024;
+
+template <class _Size>
+inline TEST_ALWAYS_INLINE _Size loadword(const void* __p) {
+  _Size __r;
+  std::memcpy(&__r, __p, sizeof(__r));
+  return __r;
+}
+
+inline TEST_ALWAYS_INLINE std::size_t hash_len_16(std::size_t __u, std::size_t __v) {
+  const std::size_t __mul = 0x9ddfea08eb382d69ULL;
+  std::size_t __a         = (__u ^ __v) * __mul;
+  __a ^= (__a >> 47);
+  std::size_t __b = (__v ^ __a) * __mul;
+  __b ^= (__b >> 47);
+  __b *= __mul;
+  return __b;
+}
+
+template <std::size_t _Len>
+inline TEST_ALWAYS_INLINE std::size_t hash_len_0_to_8(const char* __s) {
+  static_assert(_Len == 4 || _Len == 8, "");
+  const uint64_t __a = loadword<uint32_t>(__s);
+  const uint64_t __b = loadword<uint32_t>(__s + _Len - 4);
+  return hash_len_16(_Len + (__a << 3), __b);
+}
+
+struct UInt32Hash {
+  UInt32Hash() = default;
+  inline TEST_ALWAYS_INLINE std::size_t operator()(uint32_t data) const {
+    return hash_len_0_to_8<4>(reinterpret_cast<const char*>(&data));
+  }
+};
+
+template <class HashFn, class GenInputs>
+void BM_Hash(benchmark::State& st, HashFn fn, GenInputs gen) {
+  auto in               = gen(st.range(0));
+  const auto end        = in.data() + in.size();
+  std::size_t last_hash = 0;
+  benchmark::DoNotOptimize(&last_hash);
+  while (st.KeepRunning()) {
+    for (auto it = in.data(); it != end; ++it) {
+      benchmark::DoNotOptimize(last_hash += fn(*it));
+    }
+    benchmark::ClobberMemory();
+  }
+}
+
+BENCHMARK_CAPTURE(BM_Hash, uint32_random_std_hash, std::hash<uint32_t>{}, getRandomIntegerInputs<uint32_t>)
+    ->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash, uint32_random_custom_hash, UInt32Hash{}, getRandomIntegerInputs<uint32_t>)
+    ->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash, uint32_top_std_hash, std::hash<uint32_t>{}, getSortedTopBitsIntegerInputs<uint32_t>)
+    ->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash, uint32_top_custom_hash, UInt32Hash{}, getSortedTopBitsIntegerInputs<uint32_t>)
+    ->Arg(TestNumInputs);
+
+BENCHMARK_MAIN();
diff --git a/libcxx/test/benchmarks/unordered_set_operations.bench.cpp b/libcxx/test/benchmarks/unordered_set_operations.bench.cpp
index bcf6adda2e0219..2e42d6d345b998 100644
--- a/libcxx/test/benchmarks/unordered_set_operations.bench.cpp
+++ b/libcxx/test/benchmarks/unordered_set_operations.bench.cpp
@@ -95,13 +95,6 @@ struct UInt32Hash2 {
   }
 };
 
-struct UInt64Hash2 {
-  UInt64Hash2() = default;
-  inline TEST_ALWAYS_INLINE std::size_t operator()(uint64_t data) const {
-    return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
-  }
-};
-
 // The sole purpose of this comparator is to be used in BM_Rehash, where
 // we need something slow enough to be easily noticable in benchmark results.
 // The default implementation of operator== for strings seems to be a little
@@ -123,36 +116,6 @@ struct SlowStringEq {
   }
 };
 
-//----------------------------------------------------------------------------//
-//                               BM_Hash
-// ---------------------------------------------------------------------------//
-
-template <class HashFn, class GenInputs>
-void BM_Hash(benchmark::State& st, HashFn fn, GenInputs gen) {
-  auto in               = gen(st.range(0));
-  const auto end        = in.data() + in.size();
-  std::size_t last_hash = 0;
-  benchmark::DoNotOptimize(&last_hash);
-  while (st.KeepRunning()) {
-    for (auto it = in.data(); it != end; ++it) {
-      benchmark::DoNotOptimize(last_hash += fn(*it));
-    }
-    benchmark::ClobberMemory();
-  }
-}
-
-BENCHMARK_CAPTURE(BM_Hash, uint32_random_std_hash, std::hash<uint32_t>{}, getRandomIntegerInputs<uint32_t>)
-    ->Arg(TestNumInputs);
-
-BENCHMARK_CAPTURE(BM_Hash, uint32_random_custom_hash, UInt32Hash{}, getRandomIntegerInputs<uint32_t>)
-    ->Arg(TestNumInputs);
-
-BENCHMARK_CAPTURE(BM_Hash, uint32_top_std_hash, std::hash<uint32_t>{}, getSortedTopBitsIntegerInputs<uint32_t>)
-    ->Arg(TestNumInputs);
-
-BENCHMARK_CAPTURE(BM_Hash, uint32_top_custom_hash, UInt32Hash{}, getSortedTopBitsIntegerInputs<uint32_t>)
-    ->Arg(TestNumInputs);
-
 //----------------------------------------------------------------------------//
 //                       BM_InsertValue
 // ---------------------------------------------------------------------------//

``````````

</details>


https://github.com/llvm/llvm-project/pull/114448


More information about the libcxx-commits mailing list