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( ...@@ -1125,6 +1125,8 @@ cc_test(
visibility = ["//visibility:private"], visibility = ["//visibility:private"],
deps = [ deps = [
":strings", ":strings",
"//absl/random",
"//absl/random:distributions",
"@com_github_google_benchmark//:benchmark_main", "@com_github_google_benchmark//:benchmark_main",
"@com_google_googletest//:gtest", "@com_google_googletest//:gtest",
], ],
......
...@@ -12,15 +12,19 @@ ...@@ -12,15 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "absl/strings/str_cat.h" #include <array>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <tuple>
#include <utility>
#include "benchmark/benchmark.h" #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/string_view.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
...@@ -141,58 +145,63 @@ void BM_DoubleToString_By_SixDigits(benchmark::State& state) { ...@@ -141,58 +145,63 @@ void BM_DoubleToString_By_SixDigits(benchmark::State& state) {
} }
BENCHMARK(BM_DoubleToString_By_SixDigits); BENCHMARK(BM_DoubleToString_By_SixDigits);
template <typename... Chunks> template <typename Table, size_t... Index>
void BM_StrAppendImpl(benchmark::State& state, size_t total_bytes, void BM_StrAppendImpl(benchmark::State& state, Table table, size_t total_bytes,
Chunks... chunks) { std::index_sequence<Index...>) {
for (auto s : state) { for (auto s : state) {
const size_t table_size = table.size();
size_t i = 0;
std::string result; std::string result;
while (result.size() < total_bytes) { while (result.size() < total_bytes) {
absl::StrAppend(&result, chunks...); absl::StrAppend(&result, std::get<Index>(table[i])...);
benchmark::DoNotOptimize(result); 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 size_t total_bytes = state.range(0);
const int chunks_at_a_time = state.range(1); const int chunks_at_a_time = state.range(1);
const absl::string_view kChunk = "0123456789";
switch (chunks_at_a_time) { switch (chunks_at_a_time) {
case 1: 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: 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: case 4:
return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk, return BM_StrAppendImpl(state, std::forward<Array>(table), total_bytes,
kChunk); std::make_index_sequence<4>());
case 8: case 8:
return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk, return BM_StrAppendImpl(state, std::forward<Array>(table), total_bytes,
kChunk, kChunk, kChunk, kChunk, kChunk); std::make_index_sequence<8>());
default: default:
std::abort(); std::abort();
} }
} }
void BM_StrAppendInt(benchmark::State& state) { void BM_StrAppendStr(benchmark::State& state) {
const size_t total_bytes = state.range(0); using T = absl::string_view;
const int chunks_at_a_time = state.range(1); using Row = std::tuple<T, T, T, T, T, T, T, T>;
const size_t kChunk = 1234; 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) { template <typename T>
case 1: void BM_StrAppendInt(benchmark::State& state) {
return BM_StrAppendImpl(state, total_bytes, kChunk); absl::BitGen rng;
case 2: absl::log_uniform_int_distribution<T> dist;
return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk); std::array<std::tuple<T, T, T, T, T, T, T, T>, (1 << 7)> table;
case 4: for (size_t i = 0; i < table.size(); ++i) {
return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk, table[i] = {dist(rng), dist(rng), dist(rng), dist(rng),
kChunk); dist(rng), dist(rng), dist(rng), dist(rng)};
case 8:
return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk,
kChunk, kChunk, kChunk, kChunk, kChunk);
default:
std::abort();
} }
return BM_StrAppend(state, table);
} }
template <typename B> template <typename B>
...@@ -207,8 +216,11 @@ void StrAppendConfig(B* benchmark) { ...@@ -207,8 +216,11 @@ void StrAppendConfig(B* benchmark) {
} }
} }
BENCHMARK(BM_StrAppend)->Apply(StrAppendConfig); BENCHMARK(BM_StrAppendStr)->Apply(StrAppendConfig);
BENCHMARK(BM_StrAppendInt)->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> template <typename... Chunks>
void BM_StrCatImpl(benchmark::State& state, 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