[libcxx-commits] [libcxx] [libc++] Optimize std::min_element (PR #100616)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Mar 27 09:09:26 PDT 2025
================
@@ -27,20 +28,115 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Iter, class _Sent, class = void>
+struct __ConstTimeDistance : false_type {};
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Iter, class _Sent>
+struct __ConstTimeDistance< _Iter, _Sent, __enable_if_t< sized_sentinel_for<_Sent, _Iter> >> : true_type {};
+
+#else
+
+template <class _Iter>
+struct __ConstTimeDistance<
+ _Iter,
+ _Iter,
+ __enable_if_t< is_same<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>::value> >
+ : true_type {};
+
+#endif // _LIBCPP_STD_VER >= 20
+
template <class _Comp, class _Iter, class _Sent, class _Proj>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
-__min_element(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter __min_element(
+ _Iter __first,
+ _Sent __last,
+ _Comp __comp,
+ _Proj& __proj,
+ /*_ConstTimeDistance*/ false_type) {
if (__first == __last)
return __first;
_Iter __i = __first;
while (++__i != __last)
if (std::__invoke(__comp, std::__invoke(__proj, *__i), std::__invoke(__proj, *__first)))
__first = __i;
-
return __first;
}
+template <class _Comp, class _Iter, class _Sent, class _Proj>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter __min_element(
+ _Iter __first,
+ _Sent __last,
+ _Comp __comp,
+ _Proj& __proj,
+ /*ConstTimeDistance*/ true_type) {
+ if (__first == __last)
+ return __first;
+
+ typedef typename std::iterator_traits<_Iter>::difference_type diff_type;
+ diff_type __n = std::distance(__first, __last);
+
+ if (__n <= 64) {
+ _Iter __i = __first;
+ while (++__i != __last)
+ if (std::__invoke(__comp, std::__invoke(__proj, *__i), std::__invoke(__proj, *__first)))
+ __first = __i;
+ return __first;
+ }
+
+ diff_type __block_size = 256;
+
+ diff_type __n_blocked = __n - (__n % __block_size);
+ _Iter __block_start = __first, __block_end = __first;
----------------
philnik777 wrote:
```suggestion
diff_type __n_blocked = __n - (__n % __block_size);
_Iter __block_start = __first;
_Iter __block_end = __first;
```
https://github.com/llvm/llvm-project/pull/100616
More information about the libcxx-commits
mailing list