Commit 6d21df71 by Abseil Team Committed by Copybara-Service

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
parent d5a2cec0
......@@ -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",
],
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment