Skip to content

Commit f9f0ae7

Browse files
committed
Draft of controlling what kind of elements are being used for benchmarks (with the goal of benchmarking SSO vs non-SSO values mainly)
1 parent 06709b9 commit f9f0ae7

File tree

2 files changed

+52
-8
lines changed

2 files changed

+52
-8
lines changed

libcxx/test/benchmarks/GenerateInput.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,31 @@ inline std::vector<const char*> getRandomCStringInputs(std::size_t N) {
171171
return cinputs;
172172
}
173173

174+
template <class T>
175+
struct Generate {
176+
// When the contents don't matter
177+
static T arbitrary();
178+
179+
// Prefer a cheap-to-construct element if possible
180+
static T cheap();
181+
182+
// Prefer an expensive-to-construct element if possible
183+
static T expensive();
184+
};
185+
186+
template <class T>
187+
requires std::integral<T>
188+
struct Generate<T> {
189+
static T arbitrary() { return 42; }
190+
static T cheap() { return 42; }
191+
static T expensive() { return 42; }
192+
};
193+
194+
template <>
195+
struct Generate<std::string> {
196+
static std::string arbitrary() { return "hello world"; }
197+
static std::string cheap() { return "small"; }
198+
static std::string expensive() { return "large stringggggggggggggggggggggggggggggggggggggggggggggggggggg"; }
199+
};
200+
174201
#endif // BENCHMARK_GENERATE_INPUT_H

libcxx/test/benchmarks/containers/container_benchmarks.h

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#ifndef TEST_BENCHMARKS_CONTAINERS_CONTAINER_BENCHMARKS_H
1111
#define TEST_BENCHMARKS_CONTAINERS_CONTAINER_BENCHMARKS_H
1212

13+
#include <algorithm>
1314
#include <cstddef>
1415
#include <iterator>
1516
#include <ranges> // for std::from_range
@@ -19,6 +20,7 @@
1920
#include "benchmark/benchmark.h"
2021
#include "test_iterators.h"
2122
#include "test_macros.h"
23+
#include "../GenerateInput.h"
2224

2325
namespace ContainerBenchmarks {
2426

@@ -47,11 +49,11 @@ void BM_ctor_size(benchmark::State& st) {
4749
}
4850
}
4951

50-
template <class Container>
51-
void BM_ctor_size_value(benchmark::State& st) {
52+
template <class Container, class Generator>
53+
void BM_ctor_size_value(benchmark::State& st, Generator gen) {
5254
using ValueType = typename Container::value_type;
5355
const auto size = st.range(0);
54-
ValueType value{};
56+
ValueType value = gen();
5557
benchmark::DoNotOptimize(value);
5658
char buffer[sizeof(Container)];
5759
for (auto _ : st) {
@@ -63,11 +65,12 @@ void BM_ctor_size_value(benchmark::State& st) {
6365
}
6466
}
6567

66-
template <class Container>
67-
void BM_ctor_iter_iter(benchmark::State& st) {
68+
template <class Container, class Generator>
69+
void BM_ctor_iter_iter(benchmark::State& st, Generator gen) {
6870
using ValueType = typename Container::value_type;
6971
const auto size = st.range(0);
70-
std::vector<ValueType> in(size);
72+
std::vector<ValueType> in;
73+
std::generate_n(std::back_inserter(in), size, gen);
7174
const auto begin = in.begin();
7275
const auto end = in.end();
7376
benchmark::DoNotOptimize(in);
@@ -283,10 +286,24 @@ void BM_erase_middle(benchmark::State& st) {
283286

284287
template <class Container>
285288
void sequence_container_benchmarks(std::string container) {
289+
using ValueType = typename Container::value_type;
290+
auto cheap = [] { return Generate<ValueType>::cheap(); };
291+
auto expensive = [] { return Generate<ValueType>::expensive(); };
292+
286293
// constructors
287294
benchmark::RegisterBenchmark(container + "::ctor(size)", BM_ctor_size<Container>)->Arg(1024);
288-
benchmark::RegisterBenchmark(container + "::ctor(size, value_type)", BM_ctor_size_value<Container>)->Arg(1024);
289-
benchmark::RegisterBenchmark(container + "::ctor(Iterator, Iterator)", BM_ctor_iter_iter<Container>)->Arg(1024);
295+
benchmark::RegisterBenchmark(container + "::ctor(size, value_type) (cheap elements)", [=](auto& st) {
296+
BM_ctor_size_value<Container>(st, cheap);
297+
})->Arg(1024);
298+
benchmark::RegisterBenchmark(container + "::ctor(size, value_type) (expensive elements)", [=](auto& st) {
299+
BM_ctor_size_value<Container>(st, expensive);
300+
})->Arg(1024);
301+
benchmark::RegisterBenchmark(container + "::ctor(Iterator, Iterator) (cheap elements)", [=](auto& st) {
302+
BM_ctor_iter_iter<Container>(st, cheap);
303+
})->Arg(1024);
304+
benchmark::RegisterBenchmark(container + "::ctor(Iterator, Iterator) (expensive elements)", [=](auto& st) {
305+
BM_ctor_iter_iter<Container>(st, expensive);
306+
})->Arg(1024);
290307
#if TEST_STD_VER >= 23
291308
benchmark::RegisterBenchmark(container + "::ctor(Range)", BM_ctor_from_range<Container>)->Arg(1024);
292309
#endif

0 commit comments

Comments
 (0)