summaryrefslogtreecommitdiff
path: root/sal/rtl
diff options
context:
space:
mode:
authorNorbert Thiebaud <nthiebaud@gmail.com>2015-07-04 21:02:35 -0500
committerStephan Bergmann <sbergman@redhat.com>2015-07-07 06:59:59 +0000
commitbb9d628552d7a91680ef04c08b1f49cee4ada6bf (patch)
treed7d3b201c86e5ffccd83734000ad61543c025f6e /sal/rtl
parent9d7727737b067c5228f129737046f718d5965659 (diff)
performance tuning of rtl_ustr_indexOfAscii_WithLength()
lcov over make check showed 98 4699997 : sal_Int32 rtl_ustr_indexOfAscii_WithLength( 99 : sal_Unicode const * str, sal_Int32 len, 100 : char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C() 101 : { 102 4699997 : assert(len >= 0); 103 4699997 : assert(subLen >= 0); 104 4699997 : if (subLen > 0 && subLen <= len) { 105 : sal_Int32 i; 106 54014537 : for (i = 0; i <= len - subLen; ++i) { 107 51036513 : if (rtl_ustr_asciil_reverseEquals_WithLength( 108 51036523 : str + i, subStr, subLen)) 109 : { 110 205482 : return i; 111 : } 112 : } 113 : } 114 4494505 : return -1; 115 : } so 1/ in 95% of the cases the result is not-found.. _that_ is the hot path 2/ we are calling rtl_ustr_asciil_reverseEquals_WithLength close to 11 times per call.. (average ~ len - subLen, due to the high miss ratio) so let's first search for the first byte of the substring to optimize the 'miss' case, which is the most common one. Change-Id: I20ef0821db2ff0db5935dd562844a947a14aff64 Reviewed-on: https://gerrit.libreoffice.org/16763 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'sal/rtl')
-rw-r--r--sal/rtl/ustring.cxx24
1 files changed, 18 insertions, 6 deletions
diff --git a/sal/rtl/ustring.cxx b/sal/rtl/ustring.cxx
index b31bc2fcddeb..9648fc63bfa7 100644
--- a/sal/rtl/ustring.cxx
+++ b/sal/rtl/ustring.cxx
@@ -27,6 +27,7 @@
#include <cstdlib>
#include <limits>
#include <stdexcept>
+#include <string>
#include <osl/diagnose.h>
#include <osl/interlck.h>
@@ -101,14 +102,25 @@ sal_Int32 rtl_ustr_indexOfAscii_WithLength(
{
assert(len >= 0);
assert(subLen >= 0);
- if (subLen > 0 && subLen <= len) {
- sal_Int32 i;
- for (i = 0; i <= len - subLen; ++i) {
- if (rtl_ustr_asciil_reverseEquals_WithLength(
- str + i, subStr, subLen))
+ if (subLen > 0 && subLen <= len)
+ {
+ sal_Unicode const* end = str + len;
+ sal_Unicode const* cursor = str;
+
+ while(cursor < end)
+ {
+ cursor = std::char_traits<sal_Unicode>::find(cursor, end - cursor, *subStr);
+ if(!cursor || (end - cursor < subLen))
{
- return i;
+ /* no enough left to actually have a match */
+ break;
+ }
+ /* now it is worth trying a full match */
+ if (rtl_ustr_asciil_reverseEquals_WithLength(cursor, subStr, subLen))
+ {
+ return cursor - str;
}
+ cursor += 1;
}
}
return -1;