From 9b5a965efd128b85a70c3912498fe42c454899fe Mon Sep 17 00:00:00 2001 From: Mitsuru Kariya Date: Sun, 29 Mar 2015 18:12:52 +0900 Subject: [PATCH] reduce includes' complexity on some inputs cf. http://melpon.org/wandbox/permlink/mVNO3IDW8aawsRtD --- sprout/algorithm/includes.hpp | 45 ++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/sprout/algorithm/includes.hpp b/sprout/algorithm/includes.hpp index 7ed069eb..5d4f6524 100644 --- a/sprout/algorithm/includes.hpp +++ b/sprout/algorithm/includes.hpp @@ -19,24 +19,29 @@ namespace sprout { namespace detail { template - inline SPROUT_CONSTEXPR InputIterator2 + inline SPROUT_CONSTEXPR sprout::pair includes_impl_ra( - RandomAccessIterator1 first1, RandomAccessIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp, - typename std::iterator_traits::difference_type pivot + RandomAccessIterator1 first1, + sprout::pair current, + InputIterator2 last2, Compare comp, + typename std::iterator_traits::difference_type len ) { - return first2 == last2 ? first2 - : pivot == 0 ? (!comp(*first1, *first2) && !comp(*first2, *first1) ? sprout::next(first2) : first2) + typedef sprout::pair type; + return current.second || current.first == last2 ? current + : len == 1 ? comp(*current.first, *first1) + ? type(current.first, true) + : type(comp(*first1, *current.first) ? current.first : sprout::next(current.first), false) : sprout::detail::includes_impl_ra( - sprout::next(first1, pivot), last1, + sprout::next(first1, len / 2), sprout::detail::includes_impl_ra( - first1, sprout::next(first1, pivot), - first2, + first1, + current, last2, comp, - pivot / 2 + len / 2 ), last2, comp, - (sprout::distance(first1, last1) - pivot) / 2 + len - len / 2 ) ; } @@ -52,9 +57,11 @@ namespace sprout { { return first1 == last1 ? first2 == last2 : sprout::detail::includes_impl_ra( - first1, last1, first2, last2, comp, - sprout::distance(first1, last1) / 2 - ) + first1, + sprout::pair(first2, false), + last2, comp, + sprout::distance(first1, last1) + ).first == last2 ; } @@ -69,15 +76,19 @@ namespace sprout { { typedef sprout::pair type; return current.second == last2 || current.first == last1 ? current - : n == 1 ? !comp(*current.first, *current.second) && !comp(*current.second, *current.first) - ? type(sprout::next(current.first), sprout::next(current.second)) - : type(sprout::next(current.first), current.second) + : n == 1 + ? comp(*current.second, *current.first) + ? type(last1, current.second) + : type( + sprout::next(current.first), + comp(*current.first, *current.second) ? current.second : sprout::next(current.second) + ) : sprout::detail::includes_impl_1( sprout::detail::includes_impl_1( current, last1, last2, comp, n / 2 ), - last1, last2, comp, n - n / 2 + last1, last2, comp, n / 2 ) ; }