[libcxx-commits] [libcxx] [libc++][ranges] optimize the performance of `ranges::starts_with` (PR #84570)

Xiaoyang Liu via libcxx-commits libcxx-commits at lists.llvm.org
Mon Oct 7 19:10:53 PDT 2024


================
@@ -50,14 +54,36 @@ struct __fn {
       _Pred __pred   = {},
       _Proj1 __proj1 = {},
       _Proj2 __proj2 = {}) {
-    return __mismatch::__fn::__go(
+    if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) {
+      auto __n1 = ranges::distance(__first1, __last1);
+      auto __n2 = ranges::distance(__first2, __last2);
+      if (__n2 == 0) {
+        return true;
+      }
+      if (__n2 > __n1) {
+        return false;
+      }
+
+      if constexpr (contiguous_iterator<_Iter1> && contiguous_iterator<_Iter2>) {
+        return ranges::equal(
+            std::move(__first1),
+            ranges::next(__first1, __n2),
+            std::move(__first2),
+            std::move(__last2),
+            std::ref(__pred),
+            std::ref(__proj1),
+            std::ref(__proj2));
+      }
+    }
+
+    return ranges::mismatch(
----------------
xiaoyang-sde wrote:

If `sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>` evaluates to `true`, but `contiguous_iterator<_Iter1> && contiguous_iterator<_Iter2>` evaluates to `false`, the code will fall back to using ranges::mismatch.

https://github.com/llvm/llvm-project/pull/84570


More information about the libcxx-commits mailing list