Skip to content

Commit 34e9a72

Browse files
committed
[libc++] Optimize __tree::__erase_unique
1 parent cbbf303 commit 34e9a72

File tree

3 files changed

+47
-42
lines changed

3 files changed

+47
-42
lines changed

libcxx/docs/ReleaseNotes/22.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ Improvements and New Features
4747
- The performance of ``map::operator=(const map&)`` has been improved by up to 11x
4848
- The performance of ``unordered_set::unordered_set(const unordered_set&)`` has been improved by up to 3.3x.
4949
- The performance of ``unordered_set::operator=(const unordered_set&)`` has been improved by up to 5x.
50+
- The performance of ``map::erase`` and ``set::erase`` has been improved by up to 2x
51+
- The performance of ``find(key)`` in ``map``, ``set``, ``multimap`` and ``multiset`` has been improved by up to 2.3x
5052

5153
Deprecations and Removals
5254
-------------------------

libcxx/include/__tree

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,9 +1038,22 @@ public:
10381038
__insert_node_at(__end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT;
10391039

10401040
template <class _Key>
1041-
_LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __v);
1041+
_LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __key) {
1042+
__end_node_pointer __parent;
1043+
__node_base_pointer __match = __find_equal(__parent, __key);
1044+
if (__match == nullptr)
1045+
return end();
1046+
return iterator(static_cast<__node_pointer>(__match));
1047+
}
1048+
10421049
template <class _Key>
1043-
_LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __v) const;
1050+
_LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __key) const {
1051+
__end_node_pointer __parent;
1052+
__node_base_pointer __match = __find_equal(__parent, __key);
1053+
if (__match == nullptr)
1054+
return end();
1055+
return const_iterator(static_cast<__node_pointer>(__match));
1056+
}
10441057

10451058
template <class _Key>
10461059
_LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
@@ -2060,25 +2073,6 @@ __tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) {
20602073
return __r;
20612074
}
20622075

2063-
template <class _Tp, class _Compare, class _Allocator>
2064-
template <class _Key>
2065-
typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) {
2066-
iterator __p = __lower_bound(__v, __root(), __end_node());
2067-
if (__p != end() && !value_comp()(__v, *__p))
2068-
return __p;
2069-
return end();
2070-
}
2071-
2072-
template <class _Tp, class _Compare, class _Allocator>
2073-
template <class _Key>
2074-
typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2075-
__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const {
2076-
const_iterator __p = __lower_bound(__v, __root(), __end_node());
2077-
if (__p != end() && !value_comp()(__v, *__p))
2078-
return __p;
2079-
return end();
2080-
}
2081-
20822076
template <class _Tp, class _Compare, class _Allocator>
20832077
template <class _Key>
20842078
typename __tree<_Tp, _Compare, _Allocator>::size_type

libcxx/test/std/containers/associative/multimap/multimap.ops/find.pass.cpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@
2121
#include "private_constructor.h"
2222
#include "is_transparent.h"
2323

24+
template <class Iter>
25+
bool iter_in_range(Iter first, Iter last, Iter to_find) {
26+
for (; first != last; ++first) {
27+
if (first == to_find)
28+
return true;
29+
}
30+
return false;
31+
}
32+
2433
int main(int, char**) {
2534
typedef std::pair<const int, double> V;
2635
{
@@ -30,15 +39,15 @@ int main(int, char**) {
3039
V ar[] = {V(5, 1), V(5, 2), V(5, 3), V(7, 1), V(7, 2), V(7, 3), V(9, 1), V(9, 2), V(9, 3)};
3140
M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
3241
R r = m.find(5);
33-
assert(r == m.begin());
42+
assert(iter_in_range(std::next(m.begin(), 0), std::next(m.begin(), 3), r));
3443
r = m.find(6);
3544
assert(r == m.end());
3645
r = m.find(7);
37-
assert(r == std::next(m.begin(), 3));
46+
assert(iter_in_range(std::next(m.begin(), 3), std::next(m.begin(), 6), r));
3847
r = m.find(8);
3948
assert(r == m.end());
4049
r = m.find(9);
41-
assert(r == std::next(m.begin(), 6));
50+
assert(iter_in_range(std::next(m.begin(), 6), std::next(m.begin(), 9), r));
4251
r = m.find(10);
4352
assert(r == m.end());
4453
}
@@ -47,15 +56,15 @@ int main(int, char**) {
4756
V ar[] = {V(5, 1), V(5, 2), V(5, 3), V(7, 1), V(7, 2), V(7, 3), V(9, 1), V(9, 2), V(9, 3)};
4857
const M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
4958
R r = m.find(5);
50-
assert(r == m.begin());
59+
assert(iter_in_range(std::next(m.begin(), 0), std::next(m.begin(), 3), r));
5160
r = m.find(6);
5261
assert(r == m.end());
5362
r = m.find(7);
54-
assert(r == std::next(m.begin(), 3));
63+
assert(iter_in_range(std::next(m.begin(), 3), std::next(m.begin(), 6), r));
5564
r = m.find(8);
5665
assert(r == m.end());
5766
r = m.find(9);
58-
assert(r == std::next(m.begin(), 6));
67+
assert(iter_in_range(std::next(m.begin(), 6), std::next(m.begin(), 9), r));
5968
r = m.find(10);
6069
assert(r == m.end());
6170
}
@@ -68,15 +77,15 @@ int main(int, char**) {
6877
V ar[] = {V(5, 1), V(5, 2), V(5, 3), V(7, 1), V(7, 2), V(7, 3), V(9, 1), V(9, 2), V(9, 3)};
6978
M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
7079
R r = m.find(5);
71-
assert(r == m.begin());
80+
assert(iter_in_range(std::next(m.begin(), 0), std::next(m.begin(), 3), r));
7281
r = m.find(6);
7382
assert(r == m.end());
7483
r = m.find(7);
75-
assert(r == std::next(m.begin(), 3));
84+
assert(iter_in_range(std::next(m.begin(), 3), std::next(m.begin(), 6), r));
7685
r = m.find(8);
7786
assert(r == m.end());
7887
r = m.find(9);
79-
assert(r == std::next(m.begin(), 6));
88+
assert(iter_in_range(std::next(m.begin(), 6), std::next(m.begin(), 9), r));
8089
r = m.find(10);
8190
assert(r == m.end());
8291
}
@@ -85,15 +94,15 @@ int main(int, char**) {
8594
V ar[] = {V(5, 1), V(5, 2), V(5, 3), V(7, 1), V(7, 2), V(7, 3), V(9, 1), V(9, 2), V(9, 3)};
8695
const M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
8796
R r = m.find(5);
88-
assert(r == m.begin());
97+
assert(iter_in_range(std::next(m.begin(), 0), std::next(m.begin(), 3), r));
8998
r = m.find(6);
9099
assert(r == m.end());
91100
r = m.find(7);
92-
assert(r == std::next(m.begin(), 3));
101+
assert(iter_in_range(std::next(m.begin(), 3), std::next(m.begin(), 6), r));
93102
r = m.find(8);
94103
assert(r == m.end());
95104
r = m.find(9);
96-
assert(r == std::next(m.begin(), 6));
105+
assert(iter_in_range(std::next(m.begin(), 6), std::next(m.begin(), 9), r));
97106
r = m.find(10);
98107
assert(r == m.end());
99108
}
@@ -107,28 +116,28 @@ int main(int, char**) {
107116
V ar[] = {V(5, 1), V(5, 2), V(5, 3), V(7, 1), V(7, 2), V(7, 3), V(9, 1), V(9, 2), V(9, 3)};
108117
M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
109118
R r = m.find(5);
110-
assert(r == m.begin());
119+
assert(iter_in_range(std::next(m.begin(), 0), std::next(m.begin(), 3), r));
111120
r = m.find(6);
112121
assert(r == m.end());
113122
r = m.find(7);
114-
assert(r == std::next(m.begin(), 3));
123+
assert(iter_in_range(std::next(m.begin(), 3), std::next(m.begin(), 6), r));
115124
r = m.find(8);
116125
assert(r == m.end());
117126
r = m.find(9);
118-
assert(r == std::next(m.begin(), 6));
127+
assert(iter_in_range(std::next(m.begin(), 6), std::next(m.begin(), 9), r));
119128
r = m.find(10);
120129
assert(r == m.end());
121130

122131
r = m.find(C2Int(5));
123-
assert(r == m.begin());
132+
assert(iter_in_range(std::next(m.begin(), 0), std::next(m.begin(), 3), r));
124133
r = m.find(C2Int(6));
125134
assert(r == m.end());
126135
r = m.find(C2Int(7));
127-
assert(r == std::next(m.begin(), 3));
136+
assert(iter_in_range(std::next(m.begin(), 3), std::next(m.begin(), 6), r));
128137
r = m.find(C2Int(8));
129138
assert(r == m.end());
130139
r = m.find(C2Int(9));
131-
assert(r == std::next(m.begin(), 6));
140+
assert(iter_in_range(std::next(m.begin(), 6), std::next(m.begin(), 9), r));
132141
r = m.find(C2Int(10));
133142
assert(r == m.end());
134143
}
@@ -150,15 +159,15 @@ int main(int, char**) {
150159
m.insert(std::make_pair<PC, double>(PC::make(9), 3));
151160

152161
R r = m.find(5);
153-
assert(r == m.begin());
162+
assert(iter_in_range(std::next(m.begin(), 0), std::next(m.begin(), 3), r));
154163
r = m.find(6);
155164
assert(r == m.end());
156165
r = m.find(7);
157-
assert(r == std::next(m.begin(), 3));
166+
assert(iter_in_range(std::next(m.begin(), 3), std::next(m.begin(), 6), r));
158167
r = m.find(8);
159168
assert(r == m.end());
160169
r = m.find(9);
161-
assert(r == std::next(m.begin(), 6));
170+
assert(iter_in_range(std::next(m.begin(), 6), std::next(m.begin(), 9), r));
162171
r = m.find(10);
163172
assert(r == m.end());
164173
}

0 commit comments

Comments
 (0)