Skip to content

Commit acc54bd

Browse files
committed
[libc++] Optimize vector<bool>::reserve
1 parent 9e25a42 commit acc54bd

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

libcxx/docs/ReleaseNotes/22.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Improvements and New Features
8282
- The ``std::{generate, generate_n}`` and ``std::ranges::generate_n`` algorithms have been optimized for segmented
8383
iterators, resulting in a performance improvement for ``std::deque<short>`` and
8484
``std::join_view<vector<vector<short>>>`` iterators.
85+
- The performance of ``vector<bool>::reserve()`` has been improved by up to 2x.
8586

8687
- The ``num_get::do_get`` integral overloads have been optimized, resulting in a performance improvement of up to 2.8x.
8788

libcxx/include/__vector/vector_bool.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,8 @@ vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator
761761
__v.__cap_ = __v.__size_ = 0;
762762
} else if (__v.size() > 0) {
763763
__vallocate(__v.size());
764-
__construct_at_end(__v.begin(), __v.end(), __v.size());
764+
__size_ = __v.__size_;
765+
std::copy_n(__v.__begin_, __external_cap_to_internal(__v.size()), __begin_);
765766
}
766767
}
767768

@@ -856,7 +857,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type _
856857
this->__throw_length_error();
857858
vector __v(this->get_allocator());
858859
__v.__vallocate(__n);
859-
__v.__construct_at_end(this->begin(), this->end(), this->size());
860+
__v.__size_ = __size_;
861+
std::copy_n(__begin_, __external_cap_to_internal(__size_), __v.__begin_);
860862
swap(__v);
861863
}
862864
}

libcxx/test/benchmarks/containers/sequence/vector_bool.bench.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include <benchmark/benchmark.h>
10+
#include <memory_resource>
1011
#include <vector>
1112

1213
static void BM_vector_bool_copy_ctor(benchmark::State& state) {
@@ -18,14 +19,49 @@ static void BM_vector_bool_copy_ctor(benchmark::State& state) {
1819
benchmark::DoNotOptimize(vec2);
1920
}
2021
}
21-
BENCHMARK(BM_vector_bool_copy_ctor);
22+
BENCHMARK(BM_vector_bool_copy_ctor)->Name("vector<bool>(const vector<bool>&)");
23+
24+
static void BM_vector_bool_move_ctor_alloc_equal(benchmark::State& state) {
25+
std::vector<bool> vec(100, true);
26+
27+
for (auto _ : state) {
28+
benchmark::DoNotOptimize(vec);
29+
std::vector<bool> vec2(std::move(vec), std::allocator<bool>());
30+
benchmark::DoNotOptimize(vec2);
31+
swap(vec, vec2);
32+
}
33+
}
34+
BENCHMARK(BM_vector_bool_move_ctor_alloc_equal)
35+
->Name("vector<bool>(vector<bool>&&, const allocator_type&) (equal allocators)");
36+
37+
static void BM_vector_bool_move_ctor_alloc_different(benchmark::State& state) {
38+
std::pmr::monotonic_buffer_resource resource;
39+
std::pmr::vector<bool> vec(100, true, &resource);
40+
41+
for (auto _ : state) {
42+
benchmark::DoNotOptimize(vec);
43+
std::pmr::vector<bool> vec2(std::move(vec), std::pmr::new_delete_resource());
44+
benchmark::DoNotOptimize(vec2);
45+
}
46+
}
47+
BENCHMARK(BM_vector_bool_move_ctor_alloc_different)
48+
->Name("vector<bool>(vector<bool>&&, const allocator_type&) (different allocators)");
2249

2350
static void BM_vector_bool_size_ctor(benchmark::State& state) {
2451
for (auto _ : state) {
2552
std::vector<bool> vec(100, true);
2653
benchmark::DoNotOptimize(vec);
2754
}
2855
}
29-
BENCHMARK(BM_vector_bool_size_ctor);
56+
BENCHMARK(BM_vector_bool_size_ctor)->Name("vector<bool>(size_type, const value_type&)");
57+
58+
static void BM_vector_bool_reserve(benchmark::State& state) {
59+
for (auto _ : state) {
60+
std::vector<bool> vec;
61+
vec.reserve(100);
62+
benchmark::DoNotOptimize(vec);
63+
}
64+
}
65+
BENCHMARK(BM_vector_bool_reserve)->Name("vector<bool>::reserve()");
3066

3167
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)