aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2017-01-09 13:05:58 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2017-01-09 13:05:58 +0000
commitcb627cdf5c0761f9e1be587a1416db9446a4801b (patch)
tree46f37e5514f528ae92eb070447b2bf14ee402a03
parentf63d601b9629ffbf756c97dac2d4241ed43d9e4e (diff)
downloadgcc-cb627cdf5c0761f9e1be587a1416db9446a4801b.zip
gcc-cb627cdf5c0761f9e1be587a1416db9446a4801b.tar.gz
gcc-cb627cdf5c0761f9e1be587a1416db9446a4801b.tar.bz2
PR66414 optimize std::string::find
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
-rw-r--r--libstdc++-v3/ChangeLog7
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc26
2 files changed, 26 insertions, 7 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index cab1848..79b12cc 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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.
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 8b2895b..41b7fa1 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -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;
}