Cleanups related to benchmarks
  * Fix many benchmarks to be cc_binary instead of cc_test
  * Add a few benchmarks for StrFormat
  * Add benchmarks for Substitute
  * Add benchmarks for Damerau-Levenshtein distance used in flags

PiperOrigin-RevId: 738448552
Change-Id: I521f4b2ef9116c9895b44c32d27e94507380bee8
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 5e67a65..83fd607 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -699,8 +699,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "thread_identity_benchmark",
+    testonly = True,
     srcs = ["internal/thread_identity_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -710,7 +711,6 @@
         ":base",
         "//absl/synchronization",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
diff --git a/absl/base/internal/thread_identity_benchmark.cc b/absl/base/internal/thread_identity_benchmark.cc
index 0ae10f2..419e82d 100644
--- a/absl/base/internal/thread_identity_benchmark.cc
+++ b/absl/base/internal/thread_identity_benchmark.cc
@@ -12,10 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/thread_identity.h"
 #include "absl/synchronization/internal/create_thread_identity.h"
 #include "absl/synchronization/internal/per_thread_sem.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index 37b5f2a..ccaed1c 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -1148,6 +1148,5 @@
         "//absl/strings:str_format",
         "//absl/time",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
diff --git a/absl/container/btree_benchmark.cc b/absl/container/btree_benchmark.cc
index b1525bd..ee4efbd 100644
--- a/absl/container/btree_benchmark.cc
+++ b/absl/container/btree_benchmark.cc
@@ -26,7 +26,6 @@
 #include <unordered_set>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/algorithm/container.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/container/btree_map.h"
@@ -42,6 +41,7 @@
 #include "absl/strings/cord.h"
 #include "absl/strings/str_format.h"
 #include "absl/time/time.h"
+#include "benchmark/benchmark.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
diff --git a/absl/functional/BUILD.bazel b/absl/functional/BUILD.bazel
index 8296f14..aeed3b6 100644
--- a/absl/functional/BUILD.bazel
+++ b/absl/functional/BUILD.bazel
@@ -146,8 +146,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "function_type_benchmark",
+    testonly = True,
     srcs = [
         "function_type_benchmark.cc",
     ],
@@ -159,6 +160,5 @@
         ":function_ref",
         "//absl/base:core_headers",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
diff --git a/absl/functional/function_type_benchmark.cc b/absl/functional/function_type_benchmark.cc
index 03dc31d..513233b 100644
--- a/absl/functional/function_type_benchmark.cc
+++ b/absl/functional/function_type_benchmark.cc
@@ -16,10 +16,10 @@
 #include <memory>
 #include <string>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/attributes.h"
 #include "absl/functional/any_invocable.h"
 #include "absl/functional/function_ref.h"
+#include "benchmark/benchmark.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel
index 4503a15..3c7a02f 100644
--- a/absl/numeric/BUILD.bazel
+++ b/absl/numeric/BUILD.bazel
@@ -56,7 +56,6 @@
         "//absl/base:core_headers",
         "//absl/random",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -115,8 +114,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "int128_benchmark",
+    testonly = True,
     srcs = ["int128_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -125,7 +125,6 @@
         ":int128",
         "//absl/base:config",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
diff --git a/absl/numeric/bits_benchmark.cc b/absl/numeric/bits_benchmark.cc
index 2c89afd..429b4ca 100644
--- a/absl/numeric/bits_benchmark.cc
+++ b/absl/numeric/bits_benchmark.cc
@@ -15,10 +15,10 @@
 #include <cstdint>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/optimization.h"
 #include "absl/numeric/bits.h"
 #include "absl/random/random.h"
+#include "benchmark/benchmark.h"
 
 namespace absl {
 namespace {
diff --git a/absl/numeric/int128_benchmark.cc b/absl/numeric/int128_benchmark.cc
index eab1515..e2e2de5 100644
--- a/absl/numeric/int128_benchmark.cc
+++ b/absl/numeric/int128_benchmark.cc
@@ -18,9 +18,9 @@
 #include <random>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/config.h"
 #include "absl/numeric/int128.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index cb8d900..ddc115d 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -172,8 +172,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "escaping_benchmark",
+    testonly = True,
     srcs = [
         "escaping_benchmark.cc",
         "internal/escaping_test_common.h",
@@ -185,7 +186,6 @@
         ":strings",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -241,8 +241,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "ascii_benchmark",
+    testonly = True,
     srcs = ["ascii_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -250,7 +251,6 @@
     deps = [
         ":strings",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -268,8 +268,25 @@
     ],
 )
 
-cc_test(
+cc_binary(
+    name = "damerau_levenshtein_distance_benchmark",
+    testonly = True,
+    srcs = [
+        "internal/damerau_levenshtein_distance_benchmark.cc",
+    ],
+    copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    tags = ["benchmark"],
+    visibility = ["//visibility:private"],
+    deps = [
+        ":strings",
+        "@google_benchmark//:benchmark_main",
+    ],
+)
+
+cc_binary(
     name = "memutil_benchmark",
+    testonly = True,
     srcs = [
         "internal/memutil.h",
         "internal/memutil_benchmark.cc",
@@ -281,7 +298,6 @@
         ":strings",
         "//absl/base:core_headers",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -332,8 +348,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "string_view_benchmark",
+    testonly = True,
     srcs = ["string_view_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -344,7 +361,6 @@
         "//absl/base:core_headers",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -365,9 +381,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "charset_benchmark",
-    size = "small",
+    testonly = True,
     srcs = [
         "charset_benchmark.cc",
     ],
@@ -380,7 +396,6 @@
         ":charset",
         "//absl/log:check",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -928,7 +943,6 @@
     srcs = ["cordz_test.cc"],
     copts = ABSL_TEST_COPTS,
     tags = [
-        "benchmark",
         "no_test_android_arm",
         "no_test_android_arm64",
         "no_test_android_x86",
@@ -970,8 +984,25 @@
     ],
 )
 
-cc_test(
+cc_binary(
+    name = "substitute_benchmark",
+    testonly = True,
+    srcs = ["substitute_benchmark.cc"],
+    copts = ABSL_TEST_COPTS,
+    tags = [
+        "benchmark",
+    ],
+    visibility = ["//visibility:private"],
+    deps = [
+        ":strings",
+        "//absl/base:core_headers",
+        "@google_benchmark//:benchmark_main",
+    ],
+)
+
+cc_binary(
     name = "str_replace_benchmark",
+    testonly = True,
     srcs = ["str_replace_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -980,7 +1011,6 @@
         ":strings",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1014,8 +1044,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "str_split_benchmark",
+    testonly = True,
     srcs = ["str_split_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -1024,7 +1055,6 @@
         ":strings",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1041,8 +1071,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "ostringstream_benchmark",
+    testonly = True,
     srcs = ["internal/ostringstream_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -1050,7 +1081,6 @@
     deps = [
         ":internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1086,8 +1116,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "str_join_benchmark",
+    testonly = True,
     srcs = ["str_join_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -1095,7 +1126,6 @@
     deps = [
         ":strings",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1114,18 +1144,19 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "str_cat_benchmark",
+    testonly = True,
     srcs = ["str_cat_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
     visibility = ["//visibility:private"],
     deps = [
+        ":str_format",
         ":strings",
         "//absl/random",
         "//absl/random:distributions",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1152,8 +1183,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "numbers_benchmark",
+    testonly = True,
     srcs = ["numbers_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -1164,7 +1196,6 @@
         "//absl/random",
         "//absl/random:distributions",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1226,8 +1257,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "charconv_benchmark",
+    testonly = True,
     srcs = [
         "charconv_benchmark.cc",
     ],
@@ -1237,7 +1269,6 @@
     deps = [
         ":strings",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
diff --git a/absl/strings/ascii_benchmark.cc b/absl/strings/ascii_benchmark.cc
index e4d0196..a839019 100644
--- a/absl/strings/ascii_benchmark.cc
+++ b/absl/strings/ascii_benchmark.cc
@@ -12,15 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/ascii.h"
-
 #include <algorithm>
+#include <array>
 #include <cctype>
 #include <cstddef>
-#include <string>
-#include <array>
 #include <random>
+#include <string>
 
+#include "absl/strings/ascii.h"
 #include "benchmark/benchmark.h"
 
 namespace {
diff --git a/absl/strings/charconv_benchmark.cc b/absl/strings/charconv_benchmark.cc
index e8c7371..0ee9363 100644
--- a/absl/strings/charconv_benchmark.cc
+++ b/absl/strings/charconv_benchmark.cc
@@ -12,12 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/charconv.h"
-
 #include <cstdlib>
 #include <cstring>
 #include <string>
 
+#include "absl/strings/charconv.h"
 #include "benchmark/benchmark.h"
 
 namespace {
diff --git a/absl/strings/charset_benchmark.cc b/absl/strings/charset_benchmark.cc
index bf7ae56..7133985 100644
--- a/absl/strings/charset_benchmark.cc
+++ b/absl/strings/charset_benchmark.cc
@@ -14,9 +14,9 @@
 
 #include <cstdint>
 
-#include "benchmark/benchmark.h"
 #include "absl/log/check.h"
 #include "absl/strings/charset.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/escaping_benchmark.cc b/absl/strings/escaping_benchmark.cc
index 342fd14..32b8f6e 100644
--- a/absl/strings/escaping_benchmark.cc
+++ b/absl/strings/escaping_benchmark.cc
@@ -12,18 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/escaping.h"
-
 #include <cstdint>
 #include <memory>
 #include <random>
 #include <string>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/internal/escaping_test_common.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc b/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc
new file mode 100644
index 0000000..76d6db4
--- /dev/null
+++ b/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc
@@ -0,0 +1,56 @@
+// Copyright 2022 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+
+#include "absl/strings/internal/damerau_levenshtein_distance.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+
+std::string MakeTestString(int desired_length, int num_edits) {
+  std::string test(desired_length, 'x');
+  for (int i = 0; (i < num_edits) && (i * 8 < desired_length); ++i) {
+    test[i * 8] = 'y';
+  }
+  return test;
+}
+
+void BenchmarkArgs(benchmark::internal::Benchmark* benchmark) {
+  // Each column is 8 bytes.
+  const auto string_size = {1, 8, 64, 100};
+  const auto num_edits = {1, 2, 16, 16, 64, 80};
+  const auto distance_cap = {1, 2, 3, 16, 64, 80};
+  for (const int s : string_size) {
+    for (const int n : num_edits) {
+      for (const int d : distance_cap) {
+        if (n > s) continue;
+        benchmark->Args({s, n, d});
+      }
+    }
+  }
+}
+
+using absl::strings_internal::CappedDamerauLevenshteinDistance;
+void BM_Distance(benchmark::State& state) {
+  std::string s1 = MakeTestString(state.range(0), 0);
+  std::string s2 = MakeTestString(state.range(0), state.range(1));
+  const size_t cap = state.range(2);
+  for (auto _ : state) {
+    CappedDamerauLevenshteinDistance(s1, s2, cap);
+  }
+}
+BENCHMARK(BM_Distance)->Apply(BenchmarkArgs);
+
+}  // namespace
diff --git a/absl/strings/internal/memutil_benchmark.cc b/absl/strings/internal/memutil_benchmark.cc
index 61e323a..1186752 100644
--- a/absl/strings/internal/memutil_benchmark.cc
+++ b/absl/strings/internal/memutil_benchmark.cc
@@ -12,13 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/internal/memutil.h"
-
 #include <algorithm>
 #include <cstdlib>
 
-#include "benchmark/benchmark.h"
 #include "absl/strings/ascii.h"
+#include "absl/strings/internal/memutil.h"
+#include "benchmark/benchmark.h"
 
 // We fill the haystack with aaaaaaaaaaaaaaaaaa...aaaab.
 // That gives us:
diff --git a/absl/strings/internal/ostringstream_benchmark.cc b/absl/strings/internal/ostringstream_benchmark.cc
index 5979f18..a95cf4d 100644
--- a/absl/strings/internal/ostringstream_benchmark.cc
+++ b/absl/strings/internal/ostringstream_benchmark.cc
@@ -12,11 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/internal/ostringstream.h"
-
 #include <sstream>
 #include <string>
 
+#include "absl/strings/internal/ostringstream.h"
 #include "benchmark/benchmark.h"
 
 namespace {
diff --git a/absl/strings/numbers_benchmark.cc b/absl/strings/numbers_benchmark.cc
index e7cb60a..c58f861 100644
--- a/absl/strings/numbers_benchmark.cc
+++ b/absl/strings/numbers_benchmark.cc
@@ -19,12 +19,12 @@
 #include <type_traits>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/random/distributions.h"
 #include "absl/random/random.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/string_view.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/str_cat_benchmark.cc b/absl/strings/str_cat_benchmark.cc
index 0a851e7..7695e8f 100644
--- a/absl/strings/str_cat_benchmark.cc
+++ b/absl/strings/str_cat_benchmark.cc
@@ -21,12 +21,13 @@
 #include <tuple>
 #include <utility>
 
-#include "benchmark/benchmark.h"
 #include "absl/random/log_uniform_int_distribution.h"
 #include "absl/random/random.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
 #include "absl/strings/string_view.h"
 #include "absl/strings/substitute.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
@@ -111,6 +112,17 @@
 }
 BENCHMARK(BM_HexCat_By_StrCat);
 
+void BM_HexCat_By_StrFormat(benchmark::State& state) {
+  int i = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::StrFormat("%s %x", kStringOne, int64_t{i} + 0x10000000);
+    benchmark::DoNotOptimize(result);
+    i = IncrementAlternatingSign(i);
+  }
+}
+BENCHMARK(BM_HexCat_By_StrFormat);
+
 void BM_HexCat_By_Substitute(benchmark::State& state) {
   int i = 0;
   for (auto _ : state) {
@@ -145,6 +157,18 @@
 }
 BENCHMARK(BM_DoubleToString_By_SixDigits);
 
+void BM_FloatToString_By_StrFormat(benchmark::State& state) {
+  int i = 0;
+  float foo = 0.0f;
+  for (auto _ : state) {
+    std::string result =
+        absl::StrFormat("%f != %lld", foo += 1.001f, int64_t{i});
+    benchmark::DoNotOptimize(result);
+    i = IncrementAlternatingSign(i);
+  }
+}
+BENCHMARK(BM_FloatToString_By_StrFormat);
+
 template <typename Table, size_t... Index>
 void BM_StrAppendImpl(benchmark::State& state, Table table, size_t total_bytes,
                       std::index_sequence<Index...>) {
diff --git a/absl/strings/str_join_benchmark.cc b/absl/strings/str_join_benchmark.cc
index be7a725..ffe6696 100644
--- a/absl/strings/str_join_benchmark.cc
+++ b/absl/strings/str_join_benchmark.cc
@@ -13,13 +13,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/str_join.h"
-
 #include <string>
 #include <tuple>
-#include <vector>
 #include <utility>
+#include <vector>
 
+#include "absl/strings/str_join.h"
 #include "benchmark/benchmark.h"
 
 namespace {
diff --git a/absl/strings/str_replace_benchmark.cc b/absl/strings/str_replace_benchmark.cc
index 01331da..cbe7572 100644
--- a/absl/strings/str_replace_benchmark.cc
+++ b/absl/strings/str_replace_benchmark.cc
@@ -12,13 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/str_replace.h"
-
 #include <cstring>
 #include <string>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/strings/str_replace.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/str_split_benchmark.cc b/absl/strings/str_split_benchmark.cc
index 003a66b..5a2e953 100644
--- a/absl/strings/str_split_benchmark.cc
+++ b/absl/strings/str_split_benchmark.cc
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/str_split.h"
-
 #include <cstddef>
 #include <iterator>
 #include <string>
@@ -21,9 +19,10 @@
 #include <unordered_set>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/strings/str_split.h"
 #include "absl/strings/string_view.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/string_view_benchmark.cc b/absl/strings/string_view_benchmark.cc
index 98f747c..4e36687 100644
--- a/absl/strings/string_view_benchmark.cc
+++ b/absl/strings/string_view_benchmark.cc
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/string_view.h"
-
 #include <algorithm>
 #include <cstddef>
 #include <cstdint>
@@ -23,11 +21,12 @@
 #include <unordered_set>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/attributes.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/substitute_benchmark.cc b/absl/strings/substitute_benchmark.cc
new file mode 100644
index 0000000..e58ec86
--- /dev/null
+++ b/absl/strings/substitute_benchmark.cc
@@ -0,0 +1,158 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/substitute.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+
+void BM_Substitute(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $$", s,
+                                          s, s, s, s, s, s, s, s, s);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_Substitute)->Range(0, 1024);
+
+// Like BM_Substitute, but use char* strings (which must then be copied
+// to STL strings) for all parameters.  This demonstrates that it is faster
+// to use absl::Substitute() even if your inputs are char* strings.
+void BM_SubstituteCstr(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $$", s.c_str(),
+                         s.c_str(), s.c_str(), s.c_str(), s.c_str(), s.c_str(),
+                         s.c_str(), s.c_str(), s.c_str(), s.c_str());
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_SubstituteCstr)->Range(0, 1024);
+
+// For comparison with BM_Substitute.
+void BM_StringPrintf(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::StrCat(s, " ", s, " ", s, " ", s, " ", s, " ", s,
+                                      " ", s, " ", s, " ", s, " ", s);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_StringPrintf)->Range(0, 1024);
+
+// Benchmark using absl::Substitute() together with SimpleItoa() to print
+// numbers.  This demonstrates that absl::Substitute() is faster than
+// StringPrintf() even when the inputs are numbers.
+void BM_SubstituteNumber(benchmark::State& state) {
+  const int n = state.range(0);
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $$", n, n + 1, n + 2,
+                         n + 3, n + 4, n + 5, n + 6, n + 7, n + 8, n + 9);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_SubstituteNumber)->Arg(0)->Arg(1 << 20);
+
+// For comparison with BM_SubstituteNumber.
+void BM_StrCatNumber(benchmark::State& state) {
+  const int n = state.range(0);
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::StrCat(n, " ", n + 1, " ", n + 2, " ", n + 3, " ", n + 4, " ",
+                     n + 5, " ", n + 6, " ", n + 7, " ", n + 8, " ", n + 9);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_StrCatNumber)->Arg(0)->Arg(1 << 20);
+
+// Benchmark using absl::Substitute() with a single substitution, to test the
+// speed at which it copies simple text.  Even in this case, it's faster
+// that StringPrintf().
+void BM_SubstituteSimpleText(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::Substitute("$0", s.c_str());
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_SubstituteSimpleText)->Range(0, 1024);
+
+// For comparison with BM_SubstituteSimpleText.
+void BM_StrCatSimpleText(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::StrCat("", s);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_StrCatSimpleText)->Range(0, 1024);
+
+std::string MakeFormatByDensity(int density, bool subs_mode) {
+  std::string format((2 + density) * 10, 'x');
+  for (size_t i = 0; i < 10; ++i) {
+    format[density * i] = subs_mode ? '$' : '%';
+    format[density * i + 1] = subs_mode ? ('0' + i) : 's';
+  }
+  return format;
+}
+
+void BM_SubstituteDensity(benchmark::State& state) {
+  const std::string s(10, 'x');
+  const std::string format = MakeFormatByDensity(state.range(0), true);
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::Substitute(format, s, s, s, s, s, s, s, s, s, s);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_SubstituteDensity)->Range(0, 256);
+
+void BM_StrCatDensity(benchmark::State& state) {
+  const std::string s(10, 'x');
+  const std::string format(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::StrCat(s, format, s, format, s, format, s, format, s, format, s,
+                     format, s, format, s, format, s, format, s, format);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_StrCatDensity)->Range(0, 256);
+
+}  // namespace
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel
index 867e986..9b01603 100644
--- a/absl/synchronization/BUILD.bazel
+++ b/absl/synchronization/BUILD.bazel
@@ -230,7 +230,6 @@
         ":graphcycles_internal",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
diff --git a/absl/synchronization/internal/graphcycles_benchmark.cc b/absl/synchronization/internal/graphcycles_benchmark.cc
index 54823e0..9012801 100644
--- a/absl/synchronization/internal/graphcycles_benchmark.cc
+++ b/absl/synchronization/internal/graphcycles_benchmark.cc
@@ -12,14 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/synchronization/internal/graphcycles.h"
-
 #include <algorithm>
 #include <cstdint>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/synchronization/internal/graphcycles.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel
index b577d92..445bdcc 100644
--- a/absl/time/BUILD.bazel
+++ b/absl/time/BUILD.bazel
@@ -131,8 +131,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "time_benchmark",
+    testonly = True,
     srcs = [
         "civil_time_benchmark.cc",
         "clock_benchmark.cc",