Skip to content

Commit ba3de0a

Browse files
committed
[libc++] Optimize make_heap() and sift_down()
1 parent c7fa3cf commit ba3de0a

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

libcxx/include/__algorithm/make_heap.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compar
3434
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
3535
difference_type __n = __last - __first;
3636
if (__n > 1) {
37-
// start from the first parent, there is no need to consider children
38-
for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) {
37+
difference_type __start = __n / 2;
38+
do {
39+
// start from the first parent, there is no need to consider children
40+
--__start;
3941
std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start);
40-
}
42+
} while (__start != 0);
4143
}
4244
}
4345

libcxx/include/__algorithm/sift_down.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ __sift_down(_RandomAccessIterator __first,
4444
__child = 2 * __child + 1;
4545
_RandomAccessIterator __child_i = __first + __child;
4646

47-
if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
48-
// right-child exists and is greater than left-child
49-
++__child_i;
50-
++__child;
47+
if ((__child + 1) < __len) {
48+
_RandomAccessIterator __right_child_i = _Ops::next(__child_i);
49+
if (__comp(*__child_i, *__right_child_i)) {
50+
// right-child exists and is greater than left-child
51+
__child_i = __right_child_i;
52+
++__child;
53+
}
5154
}
5255

5356
// check if we are in heap-order
@@ -61,17 +64,20 @@ __sift_down(_RandomAccessIterator __first,
6164
*__start = _Ops::__iter_move(__child_i);
6265
__start = __child_i;
6366

64-
if ((__len - 2) / 2 < __child)
67+
__child = 2 * __child + 1;
68+
if (!(__child < __len))
6569
break;
6670

6771
// recompute the child based off of the updated parent
68-
__child = 2 * __child + 1;
6972
__child_i = __first + __child;
7073

71-
if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
72-
// right-child exists and is greater than left-child
73-
++__child_i;
74-
++__child;
74+
if ((__child + 1) < __len) {
75+
_RandomAccessIterator __right_child_i = _Ops::next(__child_i);
76+
if (__comp(*__child_i, *__right_child_i)) {
77+
// right-child exists and is greater than left-child
78+
__child_i = __right_child_i;
79+
++__child;
80+
}
7581
}
7682

7783
// check if we are in heap-order

0 commit comments

Comments
 (0)