[libc++] Rename container benchmarks for consistency and precision (#181178)

This commit is contained in:
Louis Dionne 2026-03-11 13:49:09 -04:00 committed by GitHub
parent 0da4396c1e
commit b90f606c58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 32 additions and 17 deletions

View File

@ -210,3 +210,18 @@ prevent compilers from generating said debug information. Aliases inside type tr
should be annotated for the same reason.
This is enforced by the clang-tidy check ``libcpp-nodebug-on-aliases``.
Naming benchmarks
=================
Libc++ contains several benchmarks. It is helpful to observe some consistency when naming benchmarks since it makes it
easier to search for and filter benchmark names from various other tools like LNT. In particular, we name benchmarks
after the function they are measuring, with a few transformations to help filtering:
- Constructors are named ``ctor`` to make the name independent on the container being benchmarked.
- Copy and move operations use ``Self`` instead of the container type, again to make their name independent from the
container being benchmarked.
When multiple benchmarks measure the same function under different circumstances, we add context as a parenthesis
after the function signature. For example, ``std::vector<bool>::ctor(Self&&, const allocator_type&) (equal allocators)``
would be the allocator-aware move constructor for ``std::vector<bool>`` in the case of equal allocators.

View File

@ -89,7 +89,7 @@ void associative_container_benchmarks(std::string container) {
/////////////////////////
// Constructors
/////////////////////////
bench("ctor(const&)", [=](auto& st) {
bench("ctor(const Self&)", [=](auto& st) {
const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Container src(in.begin(), in.end());
@ -110,7 +110,7 @@ void associative_container_benchmarks(std::string container) {
}
});
bench("ctor(const&, alloc)", [=](auto& st) {
bench("ctor(const Self&, const allocator_type&)", [=](auto& st) {
const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Container src(in.begin(), in.end());
@ -131,7 +131,7 @@ void associative_container_benchmarks(std::string container) {
}
});
bench("ctor(&&, different allocs)", [=](auto& st) {
bench("ctor(Self&&, const allocator_type&) (different allocs)", [=](auto& st) {
using PMRContainer = adapt_operations<Container>::template rebind_alloc<
std::pmr::polymorphic_allocator<typename Container::value_type>>;
@ -213,7 +213,7 @@ void associative_container_benchmarks(std::string container) {
/////////////////////////
// Assignment
/////////////////////////
bench("operator=(const&) (into cleared Container)", [=](auto& st) {
bench("operator=(const Self&) (into cleared Container)", [=](auto& st) {
const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Container src(in.begin(), in.end());
@ -234,7 +234,7 @@ void associative_container_benchmarks(std::string container) {
}
});
bench("operator=(const&) (into partially populated Container)", [=](auto& st) {
bench("operator=(const Self&) (into partially populated Container)", [=](auto& st) {
const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Container src(in.begin(), in.end());
@ -255,7 +255,7 @@ void associative_container_benchmarks(std::string container) {
}
});
bench("operator=(const&) (into populated Container)", [=](auto& st) {
bench("operator=(const Self&) (into populated Container)", [=](auto& st) {
const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Container src(in.begin(), in.end());
@ -273,7 +273,7 @@ void associative_container_benchmarks(std::string container) {
/////////////////////////
// Insertion
/////////////////////////
bench_non_empty("insert(value) (already present)", [=](auto& st) {
bench_non_empty("insert(const value_type&) (already present)", [=](auto& st) {
const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Value to_insert = in[in.size() / 2]; // pick any existing value

View File

@ -65,7 +65,7 @@ void sequence_container_benchmarks(std::string container) {
/////////////////////////
if constexpr (std::is_constructible_v<Container, std::size_t>) {
// not all containers provide this constructor
bench("ctor(size)", [](auto& st) {
bench("ctor(size_type)", [](auto& st) {
auto const size = st.range(0);
for ([[maybe_unused]] auto _ : st) {
@ -76,7 +76,7 @@ void sequence_container_benchmarks(std::string container) {
}
for (auto gen : generators)
bench("ctor(size, value_type)" + tostr(gen), [gen](auto& st) {
bench("ctor(size_type, const value_type&)" + tostr(gen), [gen](auto& st) {
auto const size = st.range(0);
ValueType value = gen();
benchmark::DoNotOptimize(value);
@ -118,7 +118,7 @@ void sequence_container_benchmarks(std::string container) {
#endif
for (auto gen : generators)
bench("ctor(const&)" + tostr(gen), [gen](auto& st) {
bench("ctor(const Self&)" + tostr(gen), [gen](auto& st) {
auto const size = st.range(0);
Container in;
std::generate_n(std::back_inserter(in), size, gen);
@ -135,7 +135,7 @@ void sequence_container_benchmarks(std::string container) {
// Assignment
/////////////////////////
for (auto gen : generators)
bench("operator=(const&)" + tostr(gen), [gen](auto& st) {
bench("operator=(const Self&)" + tostr(gen), [gen](auto& st) {
auto const size = st.range(0);
Container in1, in2;
std::generate_n(std::back_inserter(in1), size, gen);

View File

@ -21,7 +21,7 @@ static void BM_vector_bool_copy_ctor(benchmark::State& state) {
benchmark::DoNotOptimize(vec2);
}
}
BENCHMARK(BM_vector_bool_copy_ctor)->Name("vector<bool>(const vector<bool>&)");
BENCHMARK(BM_vector_bool_copy_ctor)->Name("std::vector<bool>::ctor(const Self&)");
static void BM_vector_bool_move_ctor_alloc_equal(benchmark::State& state) {
std::vector<bool> vec(100, true);
@ -34,7 +34,7 @@ static void BM_vector_bool_move_ctor_alloc_equal(benchmark::State& state) {
}
}
BENCHMARK(BM_vector_bool_move_ctor_alloc_equal)
->Name("vector<bool>(vector<bool>&&, const allocator_type&) (equal allocators)");
->Name("std::vector<bool>::ctor(Self&&, const allocator_type&) (equal allocators)");
#if TEST_STD_VER >= 17
static void BM_vector_bool_move_ctor_alloc_different(benchmark::State& state) {
@ -48,7 +48,7 @@ static void BM_vector_bool_move_ctor_alloc_different(benchmark::State& state) {
}
}
BENCHMARK(BM_vector_bool_move_ctor_alloc_different)
->Name("vector<bool>(vector<bool>&&, const allocator_type&) (different allocators)");
->Name("std::vector<bool>::ctor(Self&&, const allocator_type&) (different allocators)");
#endif
static void BM_vector_bool_size_ctor(benchmark::State& state) {
@ -57,7 +57,7 @@ static void BM_vector_bool_size_ctor(benchmark::State& state) {
benchmark::DoNotOptimize(vec);
}
}
BENCHMARK(BM_vector_bool_size_ctor)->Name("vector<bool>(size_type, const value_type&)");
BENCHMARK(BM_vector_bool_size_ctor)->Name("std::vector<bool>::ctor(size_type, const value_type&)");
static void BM_vector_bool_reserve(benchmark::State& state) {
for (auto _ : state) {
@ -66,7 +66,7 @@ static void BM_vector_bool_reserve(benchmark::State& state) {
benchmark::DoNotOptimize(vec);
}
}
BENCHMARK(BM_vector_bool_reserve)->Name("vector<bool>::reserve()");
BENCHMARK(BM_vector_bool_reserve)->Name("std::vector<bool>::reserve()");
static void BM_vector_bool_resize(benchmark::State& state) {
for (auto _ : state) {
@ -75,6 +75,6 @@ static void BM_vector_bool_resize(benchmark::State& state) {
benchmark::DoNotOptimize(vec);
}
}
BENCHMARK(BM_vector_bool_resize)->Name("vector<bool>::resize()");
BENCHMARK(BM_vector_bool_resize)->Name("std::vector<bool>::resize()");
BENCHMARK_MAIN();