[libcxx-commits] [PATCH] D144538: Checked that complexity of std::sort_heap is 2N log(N) comparisons

Nilay Vaish via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 21 23:46:28 PST 2023


nilayvaish created this revision.
Herald added a subscriber: mgrang.
Herald added a project: All.
nilayvaish published this revision for review.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

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).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144538

Files:
  libcxx/docs/Status/Cxx20Issues.csv


Index: libcxx/docs/Status/Cxx20Issues.csv
===================================================================
--- libcxx/docs/Status/Cxx20Issues.csv
+++ libcxx/docs/Status/Cxx20Issues.csv
@@ -1,6 +1,6 @@
 "Issue #","Issue Name","Meeting","Status","First released version","Labels"
 "`2070 <https://wg21.link/LWG2070>`__","``allocate_shared``\  should use ``allocator_traits<A>::construct``\ ","Toronto","Resolved by `P0674R1 <https://wg21.link/P0674R1>`__",""
-"`2444 <https://wg21.link/LWG2444>`__","Inconsistent complexity for ``std::sort_heap``\ ","Toronto","",""
+"`2444 <https://wg21.link/LWG2444>`__","Inconsistent complexity for ``std::sort_heap``\ ","Toronto","|Nothing To Do|",""
 "`2593 <https://wg21.link/LWG2593>`__","Moved-from state of Allocators","Toronto","",""
 "`2597 <https://wg21.link/LWG2597>`__","``std::log``\  misspecified for complex numbers","Toronto","",""
 "`2783 <https://wg21.link/LWG2783>`__","``stack::emplace()``\  and ``queue::emplace()``\  should return ``decltype(auto)``\ ","Toronto","|Complete|",""


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144538.499390.patch
Type: text/x-patch
Size: 1037 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20230222/1e146fe1/attachment.bin>


More information about the libcxx-commits mailing list