[all-commits] [llvm/llvm-project] a06621: [libc++] Speed up set_intersection() by fast-forw...

Iuri Chaer via All-commits all-commits at lists.llvm.org
Thu Jul 18 13:11:45 PDT 2024


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: a0662176a9b40462aafbb17cd8eb8cf6a65e940e
      https://github.com/llvm/llvm-project/commit/a0662176a9b40462aafbb17cd8eb8cf6a65e940e
  Author: Iuri Chaer <iuri.chaer at gmail.com>
  Date:   2024-07-18 (Thu, 18 Jul 2024)

  Changed paths:
    M libcxx/benchmarks/CMakeLists.txt
    A libcxx/benchmarks/algorithms/set_intersection.bench.cpp
    M libcxx/docs/ReleaseNotes/19.rst
    M libcxx/include/__algorithm/iterator_operations.h
    M libcxx/include/__algorithm/lower_bound.h
    M libcxx/include/__algorithm/set_intersection.h
    M libcxx/test/std/algorithms/alg.sorting/alg.set.operations/set.intersection/ranges_set_intersection.pass.cpp
    A libcxx/test/std/algorithms/alg.sorting/alg.set.operations/set.intersection/set_intersection_complexity.pass.cpp
    M libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count.pass.cpp
    M libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count_sentinel.pass.cpp
    M libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_sentinel.pass.cpp
    M libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp
    M libcxx/test/std/ranges/range.adaptors/range.drop/types.h
    M libcxx/test/std/ranges/range.adaptors/range.transform/types.h
    M libcxx/test/support/test_iterators.h

  Log Message:
  -----------
   [libc++] Speed up set_intersection() by fast-forwarding over ranges of non-matching elements with one-sided binary search. (#75230)

One-sided binary search, aka meta binary search, has been in the public
domain for decades, and has the general advantage of being constant time
in the best case, with the downside of executing at most 2*log(N)
comparisons vs classic binary search's exact log(N). There are two
scenarios in which it really shines: the first one is when operating
over non-random-access iterators, because the classic algorithm requires
knowing the container's size upfront, which adds N iterator increments
to the complexity. The second one is when traversing the container in
order, trying to fast-forward to the next value: in that case the
classic algorithm requires at least O(N*log(N)) comparisons and, for
non-random-access iterators, O(N^2) iterator increments, whereas the
one-sided version will yield O(N) operations on both counts, with a
best-case of O(log(N)) comparisons which is very common in practice.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list