[libcxx-commits] [libcxx] c567e28 - [libc++] Optimize vector<bool>::reserve (#170137)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Dec 10 01:19:04 PST 2025


Author: Nikolas Klauser
Date: 2025-12-10T10:18:59+01:00
New Revision: c567e28a9d1c8f184f9cfdc6f9e1c8a6bcb8d296

URL: https://github.com/llvm/llvm-project/commit/c567e28a9d1c8f184f9cfdc6f9e1c8a6bcb8d296
DIFF: https://github.com/llvm/llvm-project/commit/c567e28a9d1c8f184f9cfdc6f9e1c8a6bcb8d296.diff

LOG: [libc++] Optimize vector<bool>::reserve (#170137)

Apple M4:
```
Benchmark                                                                      old        new    Difference    % Difference
--------------------------------------------------------------------------  ------  ----------  ------------  --------------
vector<bool>(const_vector<bool>&)                                            12.73       12.87          0.14           1.07%
vector<bool>(size_type,_const_value_type&)                                    9.39        9.41          0.02           0.22%
vector<bool>(vector<bool>&&,_const_allocator_type&)_(different_allocators)   16.87       15.22         -1.65          -9.80%
vector<bool>(vector<bool>&&,_const_allocator_type&)_(equal_allocators)        2.68        2.73          0.05           1.90%
vector<bool>::reserve()                                                      11.81        9.43         -2.38         -20.14%
Geomean                                                                       9.14        8.62         -0.53          -5.76%
```

Added: 
    

Modified: 
    libcxx/docs/ReleaseNotes/22.rst
    libcxx/include/__vector/vector_bool.h
    libcxx/test/benchmarks/containers/sequence/vector_bool.bench.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index 9f1e3d570f254..56eb0e588d81d 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -84,6 +84,7 @@ Improvements and New Features
   ``std::join_view<vector<vector<short>>>`` iterators.
 - ``std::atomic::wait`` has been refactored to accept more types to use platform native wait functions directly.
   This is guarded behind the ABI Macro ``_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE``.
+- The performance of ``vector<bool>::reserve()`` has been improved by up to 2x.
 
 - The ``num_get::do_get`` integral overloads have been optimized, resulting in a performance improvement of up to 2.8x.
 

diff  --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 6cb8f2a7fb012..ccea5110e3870 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -761,7 +761,8 @@ vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator
     __v.__cap_ = __v.__size_ = 0;
   } else if (__v.size() > 0) {
     __vallocate(__v.size());
-    __construct_at_end(__v.begin(), __v.end(), __v.size());
+    __size_ = __v.__size_;
+    std::copy_n(__v.__begin_, __external_cap_to_internal(__v.size()), __begin_);
   }
 }
 
@@ -856,7 +857,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type _
       this->__throw_length_error();
     vector __v(this->get_allocator());
     __v.__vallocate(__n);
-    __v.__construct_at_end(this->begin(), this->end(), this->size());
+    __v.__size_ = __size_;
+    std::copy_n(__begin_, __external_cap_to_internal(__size_), __v.__begin_);
     swap(__v);
   }
 }

diff  --git a/libcxx/test/benchmarks/containers/sequence/vector_bool.bench.cpp b/libcxx/test/benchmarks/containers/sequence/vector_bool.bench.cpp
index cdfc1041c6b65..68329cac8eb19 100644
--- a/libcxx/test/benchmarks/containers/sequence/vector_bool.bench.cpp
+++ b/libcxx/test/benchmarks/containers/sequence/vector_bool.bench.cpp
@@ -7,8 +7,11 @@
 //===----------------------------------------------------------------------===//
 
 #include <benchmark/benchmark.h>
+#include <memory_resource>
 #include <vector>
 
+#include "test_macros.h"
+
 static void BM_vector_bool_copy_ctor(benchmark::State& state) {
   std::vector<bool> vec(100, true);
 
@@ -18,7 +21,35 @@ static void BM_vector_bool_copy_ctor(benchmark::State& state) {
     benchmark::DoNotOptimize(vec2);
   }
 }
-BENCHMARK(BM_vector_bool_copy_ctor);
+BENCHMARK(BM_vector_bool_copy_ctor)->Name("vector<bool>(const vector<bool>&)");
+
+static void BM_vector_bool_move_ctor_alloc_equal(benchmark::State& state) {
+  std::vector<bool> vec(100, true);
+
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(vec);
+    std::vector<bool> vec2(std::move(vec), std::allocator<bool>());
+    benchmark::DoNotOptimize(vec2);
+    swap(vec, vec2);
+  }
+}
+BENCHMARK(BM_vector_bool_move_ctor_alloc_equal)
+    ->Name("vector<bool>(vector<bool>&&, const allocator_type&) (equal allocators)");
+
+#if TEST_STD_VER >= 17
+static void BM_vector_bool_move_ctor_alloc_
diff erent(benchmark::State& state) {
+  std::pmr::monotonic_buffer_resource resource;
+  std::pmr::vector<bool> vec(100, true, &resource);
+
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(vec);
+    std::pmr::vector<bool> vec2(std::move(vec), std::pmr::new_delete_resource());
+    benchmark::DoNotOptimize(vec2);
+  }
+}
+BENCHMARK(BM_vector_bool_move_ctor_alloc_
diff erent)
+    ->Name("vector<bool>(vector<bool>&&, const allocator_type&) (
diff erent allocators)");
+#endif
 
 static void BM_vector_bool_size_ctor(benchmark::State& state) {
   for (auto _ : state) {
@@ -26,6 +57,15 @@ static void BM_vector_bool_size_ctor(benchmark::State& state) {
     benchmark::DoNotOptimize(vec);
   }
 }
-BENCHMARK(BM_vector_bool_size_ctor);
+BENCHMARK(BM_vector_bool_size_ctor)->Name("vector<bool>(size_type, const value_type&)");
+
+static void BM_vector_bool_reserve(benchmark::State& state) {
+  for (auto _ : state) {
+    std::vector<bool> vec;
+    vec.reserve(100);
+    benchmark::DoNotOptimize(vec);
+  }
+}
+BENCHMARK(BM_vector_bool_reserve)->Name("vector<bool>::reserve()");
 
 BENCHMARK_MAIN();


        


More information about the libcxx-commits mailing list