Skip to content

Commit fc6edb7

Browse files
committed
[libc++] Optimize __tree::__erase_unique
1 parent d70e50b commit fc6edb7

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
@@ -45,6 +45,8 @@ Improvements and New Features
4545

4646
- The performance of ``map::map(const map&)`` has been improved up to 2.3x
4747
- The performance of ``map::operator=(const map&)`` has been improved by up to 11x
48+
- The performance of ``map::erase`` and ``set::erase`` has been improved by up to 2x
49+
- The performance of ``find(key)`` in ``map``, ``set``, ``multimap`` and ``multiset`` has been improved by up to 2.3x
4850

4951
Deprecations and Removals
5052
-------------------------

libcxx/include/__tree

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

10111011
template <class _Key>
1012-
_LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __v);
1012+
_LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __key) {
1013+
__end_node_pointer __parent;
1014+
__node_base_pointer __match = __find_equal(__parent, __key);
1015+
if (__match == nullptr)
1016+
return end();
1017+
return iterator(static_cast<__node_pointer>(__match));
1018+
}
1019+
10131020
template <class _Key>
1014-
_LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __v) const;
1021+
_LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __key) const {
1022+
__end_node_pointer __parent;
1023+
__node_base_pointer __match = __find_equal(__parent, __key);
1024+
if (__match == nullptr)
1025+
return end();
1026+
return const_iterator(static_cast<__node_pointer>(__match));
1027+
}
10151028

10161029
template <class _Key>
10171030
_LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
@@ -2031,25 +2044,6 @@ __tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) {
20312044
return __r;
20322045
}
20332046

2034-
template <class _Tp, class _Compare, class _Allocator>
2035-
template <class _Key>
2036-
typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) {
2037-
iterator __p = __lower_bound(__v, __root(), __end_node());
2038-
if (__p != end() && !value_comp()(__v, *__p))
2039-
return __p;
2040-
return end();
2041-
}
2042-
2043-
template <class _Tp, class _Compare, class _Allocator>
2044-
template <class _Key>
2045-
typename __tree<_Tp, _Compare, _Allocator>::const_iterator
2046-
__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const {
2047-
const_iterator __p = __lower_bound(__v, __root(), __end_node());
2048-
if (__p != end() && !value_comp()(__v, *__p))
2049-
return __p;
2050-
return end();
2051-
}
2052-
20532047
template <class _Tp, class _Compare, class _Allocator>
20542048
template <class _Key>
20552049
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)