[libcxx-commits] [libcxx] [libc++] Refactor the string benchmarks (PR #185397)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jul 3 09:28:11 PDT 2026


================
@@ -6,602 +6,499 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: c++03, c++11, c++14, c++17
 
 #include <algorithm>
-#include <cstdint>
-#include <cstdlib>
-#include <new>
+#include <array>
+#include <functional>
+#include <string>
 #include <vector>
 
-#include "../CartesianBenchmarks.h"
-#include "../GenerateInput.h"
 #include "benchmark/benchmark.h"
+#include "make_string.h"
 #include "test_macros.h"
 
-constexpr std::size_t MAX_STRING_LEN = 8 << 14;
-
-// Benchmark when there is no match.
-static void BM_StringFindNoMatch(benchmark::State& state) {
-  std::string s1(state.range(0), '-');
-  std::string s2(8, '*');
-  for (auto _ : state)
-    benchmark::DoNotOptimize(s1.find(s2));
-}
-BENCHMARK(BM_StringFindNoMatch)->Range(10, MAX_STRING_LEN);
-
-// Benchmark when the string matches first time.
-static void BM_StringFindAllMatch(benchmark::State& state) {
-  std::string s1(MAX_STRING_LEN, '-');
-  std::string s2(state.range(0), '-');
-  for (auto _ : state)
-    benchmark::DoNotOptimize(s1.find(s2));
-}
-BENCHMARK(BM_StringFindAllMatch)->Range(1, MAX_STRING_LEN);
-
-// Benchmark when the string matches somewhere in the end.
-static void BM_StringFindMatch1(benchmark::State& state) {
-  std::string s1(MAX_STRING_LEN / 2, '*');
-  s1 += std::string(state.range(0), '-');
-  std::string s2(state.range(0), '-');
-  for (auto _ : state)
-    benchmark::DoNotOptimize(s1.find(s2));
-}
-BENCHMARK(BM_StringFindMatch1)->Range(1, MAX_STRING_LEN / 4);
-
-// Benchmark when the string matches somewhere from middle to the end.
-static void BM_StringFindMatch2(benchmark::State& state) {
-  std::string s1(MAX_STRING_LEN / 2, '*');
-  s1 += std::string(state.range(0), '-');
-  s1 += std::string(state.range(0), '*');
-  std::string s2(state.range(0), '-');
-  for (auto _ : state)
-    benchmark::DoNotOptimize(s1.find(s2));
-}
-BENCHMARK(BM_StringFindMatch2)->Range(1, MAX_STRING_LEN / 4);
-
-static void BM_StringFindStringLiteral(benchmark::State& state) {
-  std::string s;
-
-  for (int i = 0; i < state.range(0); i++)
-    s += 'a';
-
-  s += 'b';
-
-  benchmark::DoNotOptimize(s.data());
-  benchmark::ClobberMemory();
-  size_t pos;
-
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(pos = s.find("b"));
-    benchmark::ClobberMemory();
-  }
-}
-
-BENCHMARK(BM_StringFindStringLiteral)->RangeMultiplier(2)->Range(8, 8 << 10);
-
-static void BM_StringFindCharLiteral(benchmark::State& state) {
-  std::string s;
-
-  for (int i = 0; i < state.range(0); i++)
-    s += 'a';
-
-  s += 'b';
-
-  benchmark::DoNotOptimize(s.data());
-  benchmark::ClobberMemory();
-  size_t pos;
-
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(pos = s.find('b'));
-    benchmark::ClobberMemory();
-  }
-}
-BENCHMARK(BM_StringFindCharLiteral)->RangeMultiplier(2)->Range(8, 8 << 10);
-
-static void BM_StringCtorDefault(benchmark::State& state) {
-  for (auto _ : state) {
-    std::string Default;
-    benchmark::DoNotOptimize(Default);
+std::string rename(std::string str, std::string_view replacement) {
+  while (true) {
+    auto pos = str.find("basic_string");
+    if (pos == std::string::npos)
+      return str;
+    str.replace(pos, std::strlen("basic_string"), replacement);
   }
 }
-BENCHMARK(BM_StringCtorDefault);
-
-static void BM_StringResizeAndOverwrite(benchmark::State& state) {
-  std::string str;
-
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(str);
-    str.resize_and_overwrite(10, [](char* ptr, size_t n) {
-      std::fill_n(ptr, n, 'a');
-      return n;
-    });
-    benchmark::DoNotOptimize(str);
-    str.clear();
-  }
-}
-BENCHMARK(BM_StringResizeAndOverwrite);
-
-enum class Length { Empty, Small, Large, Huge };
----------------
ldionne wrote:

I think it would make sense to retain names for the sizes you commonly use. I think you only use 5/30 now, so maybe `small` and `large`?

And do you think we don't need sizes larger than 30?

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


More information about the libcxx-commits mailing list