Skip to content

Commit dd5db8c

Browse files
committed
Address reviewer comments
1 parent ec7986a commit dd5db8c

File tree

3 files changed

+15
-34
lines changed

3 files changed

+15
-34
lines changed

libcxx/docs/ReleaseNotes/21.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ Improvements and New Features
7676
- The ``bitset::to_string`` function has been optimized, resulting in a performance improvement of up to 8.3x for bitsets
7777
with uniformly distributed zeros and ones, and up to 13.5x and 16.1x for sparse and dense bitsets, respectively.
7878

79+
- The ``std::distance`` and ``std::ranges::distance`` algorithms have been optimized for segmented iterators (e.g.,
80+
``std::join_view`` iterators), reducing the complexity from ``O(n)`` to ``O(n / segment_size)``. Benchmarks show
81+
performance improvements of over 1600x in favorable cases with large segment sizes (e.g., 1024).
82+
7983
Deprecations and Removals
8084
-------------------------
8185

libcxx/include/__iterator/distance.h

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,54 +33,35 @@ _LIBCPP_PUSH_MACROS
3333

3434
_LIBCPP_BEGIN_NAMESPACE_STD
3535

36-
#if _LIBCPP_STD_VER >= 20
37-
template <class _Iter>
38-
using __iter_distance_t _LIBCPP_NODEBUG = std::iter_difference_t<_Iter>;
39-
#else
40-
template <class _Iter>
41-
using __iter_distance_t _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type;
42-
#endif
43-
4436
template <class _InputIter, class _Sent>
45-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t<_InputIter>
37+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type
4638
__distance(_InputIter __first, _Sent __last) {
47-
__iter_distance_t<_InputIter> __r(0);
39+
typename iterator_traits<_InputIter>::difference_type __r(0);
4840
for (; __first != __last; ++__first)
4941
++__r;
5042
return __r;
5143
}
5244

5345
template <class _RandIter, __enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0>
54-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t<_RandIter>
46+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_RandIter>::difference_type
5547
__distance(_RandIter __first, _RandIter __last) {
5648
return __last - __first;
5749
}
5850

59-
template <class _SegmentedIter, class _Difference>
60-
struct __segment_distance {
61-
using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_SegmentedIter>;
62-
63-
_Difference& __r_;
64-
65-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __segment_distance(_Difference& __r) : __r_(__r) {}
66-
67-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
68-
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
69-
__r_ += std::__distance(__lfirst, __llast);
70-
}
71-
};
72-
51+
#if _LIBCPP_STD_VER >= 20
7352
template <class _SegmentedIter,
7453
__enable_if_t<!__has_random_access_iterator_category<_SegmentedIter>::value &&
7554
__is_segmented_iterator<_SegmentedIter>::value,
7655
int> = 0>
77-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t<_SegmentedIter>
56+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_SegmentedIter>::difference_type
7857
__distance(_SegmentedIter __first, _SegmentedIter __last) {
79-
using __difference_type = __iter_distance_t<_SegmentedIter>;
80-
__difference_type __r(0);
81-
std::__for_each_segment(__first, __last, std::__segment_distance<_SegmentedIter, __difference_type>(__r));
58+
typename iterator_traits<_SegmentedIter>::difference_type __r(0);
59+
std::__for_each_segment(__first, __last, [&__r](auto __lfirst, auto __llast) {
60+
__r += std::__distance(__lfirst, __llast);
61+
});
8262
return __r;
8363
}
64+
#endif // _LIBCPP_STD_VER >= 20
8465

8566
template <class _InputIter>
8667
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type
@@ -97,7 +78,7 @@ struct __distance {
9778
template <class _Ip, sentinel_for<_Ip> _Sp>
9879
requires(!sized_sentinel_for<_Sp, _Ip>)
9980
_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const {
100-
return std::__distance(std::move(__first), std::move(__last));
81+
return static_cast<iter_difference_t<_Ip>>(std::__distance(std::move(__first), std::move(__last)));
10182
}
10283

10384
template <class _Ip, sized_sentinel_for<decay_t<_Ip>> _Sp>

libcxx/test/benchmarks/iterators/distance.bench.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ int main(int argc, char** argv) {
4646
->Arg(1024)
4747
->Arg(4096)
4848
->Arg(8192);
49-
// ->Arg(1 << 14)
50-
// ->Arg(1 << 16)
51-
// ->Arg(1 << 18)
52-
// ->Arg(1 << 20);
5349
};
5450
bm.operator()<std::vector<std::vector<int>>>("std::distance(join_view(vector<vector<int>>))", std_distance, 256);
5551
bm.operator()<std::deque<std::deque<int>>>("std::distance(join_view(deque<deque<int>>))", std_distance, 256);

0 commit comments

Comments
 (0)