From 948bf580492a07da7808e3e7f81569bdcc21c1a1 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Mon, 6 Oct 2025 14:11:38 +0200 Subject: [PATCH] [libc++] Add more benchmarks for the associative container hint interfaces --- .../associative_container_benchmarks.h | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h index b39569812640b..22a6d0d753b0c 100644 --- a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h +++ b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h @@ -305,11 +305,19 @@ void associative_container_benchmarks(std::string container) { // The insert(hint, ...) methods are only relevant for ordered containers, and we lack // a good way to compute a hint for unordered ones. if constexpr (is_ordered_container) { - bench("insert(hint, value) (good hint)", [=](auto& st) { + auto insert_good_hint_bench = [=](bool bench_end_iter, auto& st) { const std::size_t size = st.range(0); std::vector in = make_value_types(generate_unique_keys(size + 1)); - Value to_insert = in.back(); - in.pop_back(); + auto skipped_val = bench_end_iter ? in.size() - 1 : in.size() / 2; + Value to_insert = in[skipped_val]; + { // Remove the element + std::vector tmp; + tmp.reserve(in.size() - 1); + for (size_t i = 0; i != in.size(); ++i) + if (i != skipped_val) + tmp.emplace_back(in[i]); + in = std::move(tmp); + } std::vector c(BatchSize, Container(in.begin(), in.end())); typename Container::iterator hints[BatchSize]; @@ -332,13 +340,23 @@ void associative_container_benchmarks(std::string container) { } st.ResumeTiming(); } - }); + }; + bench("insert(hint, value) (good hint, end)", [=](auto& state) { insert_good_hint_bench(true, state); }); + bench("insert(hint, value) (good hint, middle)", [=](auto& state) { insert_good_hint_bench(false, state); }); - bench("insert(hint, value) (bad hint)", [=](auto& st) { + auto insert_bad_hint_bench = [=](bool bench_end_iter, auto& st) { const std::size_t size = st.range(0); std::vector in = make_value_types(generate_unique_keys(size + 1)); - Value to_insert = in.back(); - in.pop_back(); + auto skipped_val = bench_end_iter ? in.size() - 1 : in.size() / 2; + Value to_insert = in[skipped_val]; + { // Remove the element + std::vector tmp; + tmp.reserve(in.size() - 1); + for (size_t i = 0; i != in.size(); ++i) + if (i != skipped_val) + tmp.emplace_back(in[i]); + in = std::move(tmp); + } std::vector c(BatchSize, Container(in.begin(), in.end())); while (st.KeepRunningBatch(BatchSize)) { @@ -355,7 +373,10 @@ void associative_container_benchmarks(std::string container) { } st.ResumeTiming(); } - }); + }; + + bench("insert(hint, value) (bad hint, end)", [=](auto& state) { insert_bad_hint_bench(true, state); }); + bench("insert(hint, value) (bad hint, middle)", [=](auto& state) { insert_bad_hint_bench(false, state); }); } bench("insert(iterator, iterator) (all new keys)", [=](auto& st) {