From bb355d1b6cea2db7c9226200448a5281ef1963b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Fri, 20 Mar 2026 15:20:29 +0100 Subject: [PATCH] Optimized segmented_mismatch: - avoid reference parameters - avoid extra "bool" information, and extra "mismatch1" parameter - Simplify implementation to help compiler optimize the code --- .../experimental/segmented_mismatch.hpp | 117 +++++++----------- 1 file changed, 47 insertions(+), 70 deletions(-) diff --git a/include/boost/container/experimental/segmented_mismatch.hpp b/include/boost/container/experimental/segmented_mismatch.hpp index 1ad3c2d..70e958a 100644 --- a/include/boost/container/experimental/segmented_mismatch.hpp +++ b/include/boost/container/experimental/segmented_mismatch.hpp @@ -40,87 +40,66 @@ struct mismatch_equal BOOST_CONTAINER_FORCEINLINE bool operator()(const T& a, const U& b) const { return a == b; } }; -template -bool mismatch_scan(InpIter1& first1_out, Sent last1, InpIter2& first2_out, BinaryPred pred) -{ - InpIter1 first1 = first1_out; - InpIter2 first2 = first2_out; - bool all_match = true; - - for (; first1 != last1; ++first1, ++first2) { - if (!pred(*first1, *first2)) { - all_match = false; - break; - } - } - - first1_out = first1; - first2_out = first2; - return all_match; -} - -template -bool segmented_mismatch_ref - (SegIter first1, SegIter last1, InpIter2& first2, OutIter1& mismatch1, BinaryPred pred, segmented_iterator_tag) +template +std::pair segmented_mismatch_dispatch + (SegIter first1, SegIter last1, InpIter2 first2, BinaryPred pred, segmented_iterator_tag) { typedef segmented_iterator_traits traits; typedef typename traits::local_iterator local_iterator; typedef typename traits::segment_iterator segment_iterator; + typedef std::pair return_t; + typedef std::pair local_return_t; + segment_iterator sfirst = traits::segment(first1); segment_iterator slast = traits::segment(last1); if(sfirst == slast) { - local_iterator lf = traits::local(first1); - if(!(mismatch_scan)(lf, traits::local(last1), first2, pred)) { - mismatch1 = traits::compose(sfirst, lf); - return false; - } + const local_iterator lf = traits::local(first1); + const local_iterator ll = traits::local(last1); + const local_return_t r = (segmented_mismatch)(lf, ll, first2, pred); + return return_t(traits::compose(sfirst, r.first), r.second); } - else { - { - local_iterator lf = traits::local(first1); - if(!(mismatch_scan)(lf, traits::end(sfirst), first2, pred)) { - mismatch1 = traits::compose(sfirst, lf); - return false; - } - } - for(++sfirst; sfirst != slast; ++sfirst) { - local_iterator lb = traits::begin(sfirst); - if(!(mismatch_scan)(lb, traits::end(sfirst), first2, pred)) { - mismatch1 = traits::compose(sfirst, lb); - return false; - } - } - { - local_iterator lb = traits::begin(sfirst); - if(!(mismatch_scan)(lb, traits::local(last1), first2, pred)) { - mismatch1 = traits::compose(sfirst, lb); - return false; - } - } + + // First segment + { + const local_iterator lf = traits::local(first1); + const local_iterator le = traits::end(sfirst); + const local_return_t r = (segmented_mismatch)(lf, le, first2, pred); + if (r.first != le) + return return_t(traits::compose(sfirst, r.first), r.second); + first2 = r.second; + } + // Middle segments + for(++sfirst; sfirst != slast; ++sfirst) { + const local_iterator lb = traits::begin(sfirst); + const local_iterator le = traits::end(sfirst); + const local_return_t r = (segmented_mismatch)(lb, le, first2, pred); + if (r.first != le) + return return_t(traits::compose(sfirst, r.first), r.second); + first2 = r.second; + } + // Last segment + { + const local_iterator lb = traits::begin(sfirst); + const local_iterator ll = traits::local(last1); + const local_return_t r = (segmented_mismatch)(lb, ll, first2, pred); + return return_t(traits::compose(sfirst, r.first), r.second); } - return true; } -template -typename algo_enable_if_c< - !Tag::value || is_sentinel::value, bool>::type -segmented_mismatch_ref(InpIter1 first1, Sent last1, InpIter2& first2_out, OutIter1& mismatch1, BinaryPred pred, Tag) +template +typename algo_enable_if_c + < !Tag::value || is_sentinel::value + , std::pair + >::type +segmented_mismatch_dispatch(InpIter1 first1, Sent last1, InpIter2 first2, BinaryPred pred, Tag) { - InpIter2 first2 = first2_out; - bool all_match = true; - - for (; first1 != last1; ++first1, ++first2) { - if (!pred(*first1, *first2)) { - mismatch1 = first1; - all_match = false; - break; - } + while (first1 != last1 && pred(*first1, *first2)) { + ++first1, ++first2; } - mismatch1 = first1; - first2_out = first2; - return all_match; + + return std::pair(first1, first2); } } // namespace detail_algo @@ -133,10 +112,8 @@ BOOST_CONTAINER_FORCEINLINE std::pair segmented_mismatch(InpIter1 first1, Sent last1, InpIter2 first2, BinaryPred pred) { typedef segmented_iterator_traits traits; - InpIter1 mismatch1(last1); - detail_algo::segmented_mismatch_ref - (first1, last1, first2, mismatch1, pred, typename traits::is_segmented_iterator()); - return std::pair(mismatch1, first2); + return detail_algo::segmented_mismatch_dispatch + (first1, last1, first2, pred, typename traits::is_segmented_iterator()); } //! Returns a pair of iterators to the first mismatching elements