Add benchmarks for basic_string::erase

Reviewers: EricWF

Subscribers: christof, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D73740

Cr-Mirrored-From: https://chromium.googlesource.com/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: c4b8c3ddc1ab15c914051faea6575cac2581aedb
diff --git a/benchmarks/string.bench.cpp b/benchmarks/string.bench.cpp
index fe8a1c5..e43ad32 100644
--- a/benchmarks/string.bench.cpp
+++ b/benchmarks/string.bench.cpp
@@ -308,6 +308,58 @@
   }
 };
 
+template <class Length, class Opaque>
+struct StringEraseToEnd {
+  static void run(benchmark::State& state) {
+    constexpr bool opaque = Opaque{} == Opacity::Opaque;
+    constexpr int kNumStrings = 4 << 10;
+    std::string strings[kNumStrings];
+    const int mid = makeString(Length()).size() / 2;
+    while (state.KeepRunningBatch(kNumStrings)) {
+      state.PauseTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i] = makeString(Length());
+      }
+      benchmark::DoNotOptimize(strings);
+      state.ResumeTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i].erase(maybeOpaque(mid, opaque),
+                         maybeOpaque(std::string::npos, opaque));
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringEraseToEnd" + Length::name() + Opaque::name();
+  }
+};
+
+template <class Length, class Opaque>
+struct StringEraseWithMove {
+  static void run(benchmark::State& state) {
+    constexpr bool opaque = Opaque{} == Opacity::Opaque;
+    constexpr int kNumStrings = 4 << 10;
+    std::string strings[kNumStrings];
+    const int n = makeString(Length()).size() / 2;
+    const int pos = n / 2;
+    while (state.KeepRunningBatch(kNumStrings)) {
+      state.PauseTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i] = makeString(Length());
+      }
+      benchmark::DoNotOptimize(strings);
+      state.ResumeTiming();
+      for (int i = 0; i < kNumStrings; ++i) {
+        strings[i].erase(maybeOpaque(pos, opaque), maybeOpaque(n, opaque));
+      }
+    }
+  }
+
+  static std::string name() {
+    return "BM_StringEraseWithMove" + Length::name() + Opaque::name();
+  }
+};
+
 template <class Opaque>
 struct StringAssignAsciizMix {
   static void run(benchmark::State& state) {
@@ -556,6 +608,8 @@
   makeCartesianProductBenchmark<StringDestroy, AllLengths>();
   makeCartesianProductBenchmark<StringResizeDefaultInit, AllLengths,
                                 AllOpacity>();
+  makeCartesianProductBenchmark<StringEraseToEnd, AllLengths, AllOpacity>();
+  makeCartesianProductBenchmark<StringEraseWithMove, AllLengths, AllOpacity>();
   makeCartesianProductBenchmark<StringRelational, AllRelations, AllLengths,
                                 AllLengths, AllDiffTypes>();
   makeCartesianProductBenchmark<StringRelationalLiteral, AllRelations,