[libcxx-commits] [libcxx] [libc++] Optimize lexicographical_compare (PR #65279)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 1 08:49:16 PDT 2024
================
@@ -11,39 +11,101 @@
#include <__algorithm/comp.h>
#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/min.h>
+#include <__algorithm/mismatch.h>
+#include <__algorithm/simd_utils.h>
+#include <__algorithm/unwrap_iter.h>
#include <__config>
+#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
+#include <__string/constexpr_c_functions.h>
+#include <__type_traits/desugars_to.h>
+#include <__type_traits/invoke.h>
+#include <__type_traits/is_equality_comparable.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_trivially_lexicographically_comparable.h>
+#include <__type_traits/is_volatile.h>
+#include <cwchar>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Compare, class _InputIterator1, class _InputIterator2>
+template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Comp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compare(
- _InputIterator1 __first1,
- _InputIterator1 __last1,
- _InputIterator2 __first2,
- _InputIterator2 __last2,
- _Compare __comp) {
- for (; __first2 != __last2; ++__first1, (void)++__first2) {
- if (__first1 == __last1 || __comp(*__first1, *__first2))
+ _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
+ while (__first2 != __last2) {
+ if (__first1 == __last1 ||
+ std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
return true;
- if (__comp(*__first2, *__first1))
+ if (std::__invoke(__comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1)))
return false;
+ ++__first1;
+ ++__first2;
}
return false;
}
+#ifndef _LIBCPP_CXX03_LANG
+
----------------
ldionne wrote:
```suggestion
// If the comparison operation is equivalent to < and that is a total order, we know that we can
// use equality comparison on that type instead to extract some information. Furthermore, if equality
// comparison on that type is trivial, the user can't observe that we're calling it.
//
// So instead of using the user-provided total order, we use std::mismatch which uses equality
// comparison (and is vectorized).
//
// In addition, if the type is trivially lexicographically comparable, we can go one step further and
// use std::memcmp directly instead of calling std::mismatch.
```
https://github.com/llvm/llvm-project/pull/65279
More information about the libcxx-commits
mailing list