Kaydet (Commit) bb9d6285 authored tarafından Norbert Thiebaud's avatar Norbert Thiebaud Kaydeden (comit) Stephan Bergmann

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/16763Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarStephan Bergmann <sbergman@redhat.com>
üst 9d772773
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <cstdlib> #include <cstdlib>
#include <limits> #include <limits>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <osl/diagnose.h> #include <osl/diagnose.h>
#include <osl/interlck.h> #include <osl/interlck.h>
...@@ -101,14 +102,25 @@ sal_Int32 rtl_ustr_indexOfAscii_WithLength( ...@@ -101,14 +102,25 @@ sal_Int32 rtl_ustr_indexOfAscii_WithLength(
{ {
assert(len >= 0); assert(len >= 0);
assert(subLen >= 0); assert(subLen >= 0);
if (subLen > 0 && subLen <= len) { if (subLen > 0 && subLen <= len)
sal_Int32 i; {
for (i = 0; i <= len - subLen; ++i) { sal_Unicode const* end = str + len;
if (rtl_ustr_asciil_reverseEquals_WithLength( sal_Unicode const* cursor = str;
str + i, subStr, subLen))
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; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment