[all-commits] [llvm/llvm-project] 1edc72: Checked that complexity of std::sort_heap is 2N lo...
Nilay Vaish via All-commits
all-commits at lists.llvm.org
Mon Mar 6 08:42:47 PST 2023
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 1edc72385a55adabc2803a0cde282c2d28785581
https://github.com/llvm/llvm-project/commit/1edc72385a55adabc2803a0cde282c2d28785581
Author: Nilay Vaish <nilayvaish at google.com>
Date: 2023-03-06 (Mon, 06 Mar 2023)
Changed paths:
M libcxx/docs/Status/Cxx20Issues.csv
R libcxx/test/libcxx/algorithms/alg.sorting/alg.heap.operations/sort.heap/complexity.pass.cpp
A libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/complexity.pass.cpp
M libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp
Log Message:
-----------
Checked that complexity of std::sort_heap is 2N log(N) comparisons
https://wg21.link/LWG2444 updated the comparison complexity of
std:sort_heap to be at most 2N log (N) where N == last - first. In the
current implementation, we invoke __pop_heap exactly N-1 times. In each
call to __pop_heap, we first go down the heap from first to possibly
last in the function __floyd_sift_down. Then, we possibly go back up in
the function __sift_up.
In the function __floyd_sift_down, there is loop in which one comparison
is made in each iteration. The loop runs till __child becomes greater
than (__len - 2) / 2. __child starts at 0 and it is at least set to 2 *
__child + 1 on each iteration. Thus, after k iterations, __child will
be at least 2^k - 1. After log(N) iterations, __child >= 2^(log(N)) -
1 = N - 1 > (__len - 2) / 2. This means that the while loop in the
function __floyd_sift_down would perform at most log(N) comparisons on
each invocation.
In the function __sift_up, there is one comparison made that will almost
always occur. After that there is a do-while loop. The comparison
function is invoked once in each iteration. In the worst case, the loop
will run till __len goes down to zero. It can start from (N-3)/2. In
each iteration, __len goes down to (__len-1) / 2. After k iterations,
__len will be at most (N - 2^(k+1) -1) / 2^(k+1). Thus, __len will
become when (N-2^(k+1)-1) < 2^(k+1) i.e. N < 2^(k+2) + 1. This means
at most log(N) - 1 iterations for the loop. So in total at most log(N)
comparison will be performed in __sift_up.
So overall for each iteration of the loop in __pop_heap, there will at
most 2 log(N) comparisons. So, the total number of comparisons is
at most 2 N log(N).
We also updated the test sort.heap/complexity.pass.cpp to test for the
number of operations.
Differential Revision: https://reviews.llvm.org/D144538
More information about the All-commits
mailing list