aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2024-01-05 11:13:25 -0800
committerCopybara-Service <copybara-worker@google.com>2024-01-05 11:14:22 -0800
commit6d21df714aa6a2ab2fc4029ca71dcff2daa03ca1 (patch)
tree218d54cb9d97898110e0044712f0f05f040e8225
parentd5a2cec006d14c6801ddeb768bf2574a1cf4fa7f (diff)
downloadabseil-cpp-6d21df714aa6a2ab2fc4029ca71dcff2daa03ca1.tar.gz
Extend BM_StrAppendInt to use log-uniform random numbers instead of constants
This follows Benford's law, which is likely also a much more accurate representation of real data than a constant. We also add benchmarks for different integer types. PiperOrigin-RevId: 596039508 Change-Id: I4862c7cfdbf5face18ae31cf0bd2fd54e47684b7
-rw-r--r--absl/strings/BUILD.bazel2
-rw-r--r--absl/strings/str_cat_benchmark.cc78
2 files changed, 47 insertions, 33 deletions
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index 3a244b5b..9cae69d0 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -1125,6 +1125,8 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":strings",
+ "//absl/random",
+ "//absl/random:distributions",
"@com_github_google_benchmark//:benchmark_main",
"@com_google_googletest//:gtest",
],
diff --git a/absl/strings/str_cat_benchmark.cc b/absl/strings/str_cat_benchmark.cc
index 36600268..0a851e7b 100644
--- a/absl/strings/str_cat_benchmark.cc
+++ b/absl/strings/str_cat_benchmark.cc
@@ -12,15 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "absl/strings/str_cat.h"
-
+#include <array>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
+#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/string_view.h"
#include "absl/strings/substitute.h"
@@ -141,58 +145,63 @@ void BM_DoubleToString_By_SixDigits(benchmark::State& state) {
}
BENCHMARK(BM_DoubleToString_By_SixDigits);
-template <typename... Chunks>
-void BM_StrAppendImpl(benchmark::State& state, size_t total_bytes,
- Chunks... chunks) {
+template <typename Table, size_t... Index>
+void BM_StrAppendImpl(benchmark::State& state, Table table, size_t total_bytes,
+ std::index_sequence<Index...>) {
for (auto s : state) {
+ const size_t table_size = table.size();
+ size_t i = 0;
std::string result;
while (result.size() < total_bytes) {
- absl::StrAppend(&result, chunks...);
+ absl::StrAppend(&result, std::get<Index>(table[i])...);
benchmark::DoNotOptimize(result);
+ ++i;
+ i -= i >= table_size ? table_size : 0;
}
}
}
-void BM_StrAppend(benchmark::State& state) {
+template <typename Array>
+void BM_StrAppend(benchmark::State& state, Array&& table) {
const size_t total_bytes = state.range(0);
const int chunks_at_a_time = state.range(1);
- const absl::string_view kChunk = "0123456789";
switch (chunks_at_a_time) {
case 1:
- return BM_StrAppendImpl(state, total_bytes, kChunk);
+ return BM_StrAppendImpl(state, std::forward<Array>(table), total_bytes,
+ std::make_index_sequence<1>());
case 2:
- return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk);
+ return BM_StrAppendImpl(state, std::forward<Array>(table), total_bytes,
+ std::make_index_sequence<2>());
case 4:
- return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk,
- kChunk);
+ return BM_StrAppendImpl(state, std::forward<Array>(table), total_bytes,
+ std::make_index_sequence<4>());
case 8:
- return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk,
- kChunk, kChunk, kChunk, kChunk, kChunk);
+ return BM_StrAppendImpl(state, std::forward<Array>(table), total_bytes,
+ std::make_index_sequence<8>());
default:
std::abort();
}
}
-void BM_StrAppendInt(benchmark::State& state) {
- const size_t total_bytes = state.range(0);
- const int chunks_at_a_time = state.range(1);
- const size_t kChunk = 1234;
+void BM_StrAppendStr(benchmark::State& state) {
+ using T = absl::string_view;
+ using Row = std::tuple<T, T, T, T, T, T, T, T>;
+ constexpr absl::string_view kChunk = "0123456789";
+ Row row = {kChunk, kChunk, kChunk, kChunk, kChunk, kChunk, kChunk, kChunk};
+ return BM_StrAppend(state, std::array<Row, 1>({row}));
+}
- switch (chunks_at_a_time) {
- case 1:
- return BM_StrAppendImpl(state, total_bytes, kChunk);
- case 2:
- return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk);
- case 4:
- return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk,
- kChunk);
- case 8:
- return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk,
- kChunk, kChunk, kChunk, kChunk, kChunk);
- default:
- std::abort();
+template <typename T>
+void BM_StrAppendInt(benchmark::State& state) {
+ absl::BitGen rng;
+ absl::log_uniform_int_distribution<T> dist;
+ std::array<std::tuple<T, T, T, T, T, T, T, T>, (1 << 7)> table;
+ for (size_t i = 0; i < table.size(); ++i) {
+ table[i] = {dist(rng), dist(rng), dist(rng), dist(rng),
+ dist(rng), dist(rng), dist(rng), dist(rng)};
}
+ return BM_StrAppend(state, table);
}
template <typename B>
@@ -207,8 +216,11 @@ void StrAppendConfig(B* benchmark) {
}
}
-BENCHMARK(BM_StrAppend)->Apply(StrAppendConfig);
-BENCHMARK(BM_StrAppendInt)->Apply(StrAppendConfig);
+BENCHMARK(BM_StrAppendStr)->Apply(StrAppendConfig);
+BENCHMARK(BM_StrAppendInt<int64_t>)->Apply(StrAppendConfig);
+BENCHMARK(BM_StrAppendInt<uint64_t>)->Apply(StrAppendConfig);
+BENCHMARK(BM_StrAppendInt<int32_t>)->Apply(StrAppendConfig);
+BENCHMARK(BM_StrAppendInt<uint32_t>)->Apply(StrAppendConfig);
template <typename... Chunks>
void BM_StrCatImpl(benchmark::State& state,