[libcxx-commits] [libcxx] [libc++] Remove empty container benchmarks that are meaningless from the associative containers (PR #175180)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jan 9 07:02:37 PST 2026
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/175180
We generally try to benchmark the empty container case in the associcative containers, since there are some case where we previously ran calculations for significant amounts of time, even though they were really not needed. However, there are some benchmarks where trying to run with an empty container doesn't make sense (e.g. when benchmarking collisions). We've worked around this a bit in the benchmarks by not actually benchmarking the empty case. This patch removes these meaningless benchmarks instead to speed up running the benchmarks.
>From be4f16e61100dacc8be9c6041dfe69dc4a8b62c9 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 9 Jan 2026 15:59:02 +0100
Subject: [PATCH] [libc++] Remove empty container benchmarks that are
meaningless from the associative containers
---
.../associative_container_benchmarks.h | 31 ++++++++++---------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
index 5dd55f244d885..907ea0d1a2cbf 100644
--- a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
+++ b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
@@ -65,6 +65,9 @@ void associative_container_benchmarks(std::string container) {
auto bench = [&](std::string operation, auto f) {
benchmark::RegisterBenchmark(container + "::" + operation, f)->Arg(0)->Arg(32)->Arg(1024)->Arg(8192);
};
+ auto bench_non_empty = [&](std::string operation, auto f) {
+ benchmark::RegisterBenchmark(container + "::" + operation, f)->Arg(32)->Arg(1024)->Arg(8192);
+ };
static constexpr bool is_multi_key_container =
!std::is_same_v<typename adapt_operations<Container>::InsertionResult,
@@ -270,8 +273,8 @@ void associative_container_benchmarks(std::string container) {
/////////////////////////
// Insertion
/////////////////////////
- bench("insert(value) (already present)", [=](auto& st) {
- const std::size_t size = st.range(0) ? st.range(0) : 1;
+ bench_non_empty("insert(value) (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
std::vector<Container> c(BatchSize, Container(in.begin(), in.end()));
@@ -319,8 +322,8 @@ void associative_container_benchmarks(std::string container) {
});
if constexpr (is_map_like && !is_multi_key_container) {
- bench("insert_or_assign(key, value) (already present)", [=](auto& st) {
- const std::size_t size = st.range(0) ? st.range(0) : 1;
+ bench_non_empty("insert_or_assign(key, value) (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
std::vector<Container> c(BatchSize, Container(in.begin(), in.end()));
@@ -529,8 +532,8 @@ void associative_container_benchmarks(std::string container) {
/////////////////////////
// Erasure
/////////////////////////
- bench("erase(key) (existent)", [=](auto& st) {
- const std::size_t size = st.range(0) ? st.range(0) : 1; // avoid empty container
+ bench_non_empty("erase(key) (existent)", [=](auto& st) {
+ const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Value element = in[in.size() / 2]; // pick any element
std::vector<Container> c(BatchSize, Container(in.begin(), in.end()));
@@ -573,8 +576,8 @@ void associative_container_benchmarks(std::string container) {
}
});
- bench("erase(iterator)", [=](auto& st) {
- const std::size_t size = st.range(0) ? st.range(0) : 1; // avoid empty container
+ bench_non_empty("erase(iterator)", [=](auto& st) {
+ const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Value element = in[in.size() / 2]; // pick any element
@@ -686,28 +689,28 @@ void associative_container_benchmarks(std::string container) {
};
auto find = [](Container const& c, Key const& key) { return c.find(key); };
- bench("find(key) (existent)", with_existent_key(find));
+ bench_non_empty("find(key) (existent)", with_existent_key(find));
bench("find(key) (non-existent)", with_nonexistent_key(find));
auto count = [](Container const& c, Key const& key) { return c.count(key); };
- bench("count(key) (existent)", with_existent_key(count));
+ bench_non_empty("count(key) (existent)", with_existent_key(count));
bench("count(key) (non-existent)", with_nonexistent_key(count));
auto contains = [](Container const& c, Key const& key) { return c.contains(key); };
- bench("contains(key) (existent)", with_existent_key(contains));
+ bench_non_empty("contains(key) (existent)", with_existent_key(contains));
bench("contains(key) (non-existent)", with_nonexistent_key(contains));
if constexpr (is_ordered_container) {
auto lower_bound = [](Container const& c, Key const& key) { return c.lower_bound(key); };
- bench("lower_bound(key) (existent)", with_existent_key(lower_bound));
+ bench_non_empty("lower_bound(key) (existent)", with_existent_key(lower_bound));
bench("lower_bound(key) (non-existent)", with_nonexistent_key(lower_bound));
auto upper_bound = [](Container const& c, Key const& key) { return c.upper_bound(key); };
- bench("upper_bound(key) (existent)", with_existent_key(upper_bound));
+ bench_non_empty("upper_bound(key) (existent)", with_existent_key(upper_bound));
bench("upper_bound(key) (non-existent)", with_nonexistent_key(upper_bound));
auto equal_range = [](Container const& c, Key const& key) { return c.equal_range(key); };
- bench("equal_range(key) (existent)", with_existent_key(equal_range));
+ bench_non_empty("equal_range(key) (existent)", with_existent_key(equal_range));
bench("equal_range(key) (non-existent)", with_nonexistent_key(equal_range));
}
}
More information about the libcxx-commits
mailing list