[libcxx-commits] [libcxx] [libc++][WIP] use linear search instead of binary search for small flat_map (PR #211794)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jul 24 06:46:55 PDT 2026
https://github.com/huixie90 created https://github.com/llvm/llvm-project/pull/211794
None
>From c0af2a86aaf5a970f1fb1f3911f500d67125244f Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Fri, 24 Jul 2026 14:46:31 +0100
Subject: [PATCH] [libc++][WIP] use linear search instead of binary search for
small flat_map
---
libcxx/include/__flat_map/flat_map.h | 8 ++++++++
.../associative/associative_container_benchmarks.h | 12 ++++++++++--
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h
index 50487cada24c0..8b15491a60dfc 100644
--- a/libcxx/include/__flat_map/flat_map.h
+++ b/libcxx/include/__flat_map/flat_map.h
@@ -15,6 +15,7 @@
#include <__algorithm/min.h>
#include <__algorithm/ranges_adjacent_find.h>
#include <__algorithm/ranges_equal.h>
+#include <__algorithm/ranges_find.h>
#include <__algorithm/ranges_inplace_merge.h>
#include <__algorithm/ranges_sort.h>
#include <__algorithm/ranges_unique.h>
@@ -64,6 +65,7 @@
#include <__vector/vector.h>
#include <initializer_list>
#include <stdexcept>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -989,6 +991,12 @@ class flat_map {
template <class _Self, class _Kp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __find_impl(_Self&& __self, const _Kp& __key) {
+ auto __key_iter = std::ranges::find(__self.__containers_.keys, __key);
+ auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
+
+ using Res = std::conditional_t<std::is_const_v<std::remove_reference_t<_Self>>, const_iterator, iterator>;
+ return Res(__key_iter, __mapped_iter);
+
auto __it = __self.lower_bound(__key);
auto __last = __self.end();
if (__it == __last || __self.__compare_(__key, __it->first)) {
diff --git a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
index a55f187d2ac80..93d06a020f759 100644
--- a/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
+++ b/libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
@@ -66,7 +66,7 @@ void associative_container_benchmarks(std::string container) {
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);
+ benchmark::RegisterBenchmark(container + "::" + operation, f)->Arg(1)->Arg(4)->Arg(8)->Arg(16)->Arg(32)->Arg(1024)->Arg(8192);
};
static constexpr bool is_multi_key_container =
@@ -692,9 +692,17 @@ void associative_container_benchmarks(std::string container) {
const std::size_t size = st.range(0);
std::vector<Value> in = make_value_types(generate_unique_keys(size));
Container c(in.begin(), in.end());
+ std::vector<Key> keys;
+ for(size_t i = 0; i <in.size(); ++i) {
+ keys.push_back(get_key(in[getRandomEngine()() % in.size()]));
+ }
+ size_t i = 0;
for (auto _ : st) {
- auto result = func(c, get_key(in[getRandomEngine()() % in.size()]));
+ //st.PauseTiming();
+ const auto& key = keys[++i%keys.size()];
+ //st.ResumeTiming();
+ auto result = func(c, key);
benchmark::DoNotOptimize(c);
benchmark::DoNotOptimize(result);
benchmark::ClobberMemory();
More information about the libcxx-commits
mailing list