libstdc++: std::includes performance tweak
authorMarc Glisse <marc.glisse@inria.fr>
Fri, 19 Jun 2020 12:03:45 +0000 (13:03 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Fri, 19 Jun 2020 12:03:45 +0000 (13:03 +0100)
A small tweak to the implementation of __includes, which in my
application saves 20% of the running time. I noticed it because using
range-v3 was giving unexpected performance gains.

Some of the gain comes from pulling the 2 calls ++__first1 out of the
condition so there is just one call. And most of the gain comes from
replacing the resulting

if (__comp(__first1, __first2))
  ;
else
  ++__first2;

with

if (!__comp(__first1, __first2))
  ++__first2;

I was very surprised that the code ended up being so different for such
a change, and I still don't really understand where the extra time is
going...

Anyway, while I blame the compiler for not generating very good code
with the current implementation, I believe the change can be seen as a
simplification.

libstdc++-v3/ChangeLog:

* include/bits/stl_algo.h (__includes): Simplify the code.

libstdc++-v3/include/bits/stl_algo.h

index fd6edd0..550a15f 100644 (file)
@@ -2783,15 +2783,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
               _Compare __comp)
     {
       while (__first1 != __last1 && __first2 != __last2)
-       if (__comp(__first2, __first1))
-         return false;
-       else if (__comp(__first1, __first2))
-         ++__first1;
-       else
-         {
-           ++__first1;
+       {
+         if (__comp(__first2, __first1))
+           return false;
+         if (!__comp(__first1, __first2))
            ++__first2;
-         }
+         ++__first1;
+       }
 
       return __first2 == __last2;
     }