PR66414 optimize std::string::find
authorJonathan Wakely <jwakely@redhat.com>
Mon, 9 Jan 2017 13:05:58 +0000 (13:05 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 9 Jan 2017 13:05:58 +0000 (13:05 +0000)
2017-01-09  Jonathan Wakely  <jwakely@redhat.com>
    Aditya Kumar  <hiraditya@msn.com>

PR libstdc++/66414
* include/bits/basic_string.tcc
(basic_string::find(const CharT*, size_type, size_type)): Optimize.

Co-Authored-By: Aditya Kumar <hiraditya@msn.com>
From-SVN: r244225

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.tcc

index cab18489e6ee1447ba4d89808d0337df1dcc655c..79b12ccab09eb266b0602c4f512ac09dd4eaac7e 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-09  Jonathan Wakely  <jwakely@redhat.com>
+           Aditya Kumar  <hiraditya@msn.com>
+
+       PR libstdc++/66414
+       * include/bits/basic_string.tcc
+       (basic_string::find(const CharT*, size_type, size_type)): Optimize.
+
 2017-01-06  Jonathan Wakely  <jwakely@redhat.com>
 
        * testsuite/21_strings/basic_string/operations/find/char/6.cc: New.
index 8b2895b527510cee95cb5793a2a86b32d29872b8..41b7fa196b0be530325b3faab5d627ca09c46042 100644 (file)
@@ -1190,18 +1190,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       __glibcxx_requires_string_len(__s, __n);
       const size_type __size = this->size();
-      const _CharT* __data = _M_data();
 
       if (__n == 0)
        return __pos <= __size ? __pos : npos;
+      if (__pos >= __size)
+       return npos;
 
-      if (__n <= __size)
+      const _CharT __elem0 = __s[0];
+      const _CharT* const __data = data();
+      const _CharT* __first = __data + __pos;
+      const _CharT* const __last = __data + __size;
+      size_type __len = __size - __pos;
+
+      while (__len >= __n)
        {
-         for (; __pos <= __size - __n; ++__pos)
-           if (traits_type::eq(__data[__pos], __s[0])
-               && traits_type::compare(__data + __pos + 1,
-                                       __s + 1, __n - 1) == 0)
-             return __pos;
+         // Find the first occurrence of __elem0:
+         __first = traits_type::find(__first, __len - __n + 1, __elem0);
+         if (!__first)
+           return npos;
+         // Compare the full strings from the first occurrence of __elem0.
+         // We already know that __first[0] == __s[0] but compare them again
+         // anyway because __s is probably aligned, which helps memcmp.
+         if (traits_type::compare(__first, __s, __n) == 0)
+           return __first - __data;
+         __len = __last - ++__first;
        }
       return npos;
     }