summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2015-02-20 20:57:59 +0100
committerAndras Timar <andras.timar@collabora.com>2015-03-04 03:13:25 -0800
commit8e9c0cfe86b0e6570c41ad625e1e59d289b4015e (patch)
tree667e25431509d5fc8b5bef75519904a440ea6655
parent49c4b067f5c209b40d06804c2399fb1706b92282 (diff)
tdf#89665: i18npool: fix pathological transliterate slow-path
TransliterationImpl::transliterate() has a slow-path for the case when more than one trasliteration module is cascaded which swaps 2 uno::Sequence. This is unbelievably slow because non-const Sequence::operator[] does a function call into cppu to check whether COW has to be done. This speeds up transliterate() from 344 billion to 101 billion callgrind cycles when built with GCC 4.9.2 -m32 -Os. Commit d2771b63b94a8aae3c25c83e9dae9f83242f46c1 added a second transliteration module that is enabled by default, making the problem visible, especially with long paragraphs in Writer. Change-Id: I2799df9173ac73aab8c4eb4cc6f592976b06c8da (cherry picked from commit 88d4b2fb08b983531b1e0abc71b07f4bdecdc925) Reviewed-on: https://gerrit.libreoffice.org/14644 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com> (cherry picked from commit 5e28588770fa27eb210d004aec2f56e28fe01252)
-rw-r--r--i18npool/source/transliteration/transliterationImpl.cxx10
1 files changed, 9 insertions, 1 deletions
diff --git a/i18npool/source/transliteration/transliterationImpl.cxx b/i18npool/source/transliteration/transliterationImpl.cxx
index b9e4445d63f5..20d22f0bb199 100644
--- a/i18npool/source/transliteration/transliterationImpl.cxx
+++ b/i18npool/source/transliteration/transliterationImpl.cxx
@@ -326,9 +326,17 @@ TransliterationImpl::transliterate( const OUString& inStr, sal_Int32 startPos, s
nCount = tmpStr.getLength();
+ assert(off[from].getLength() == nCount);
tmp = from; from = to; to = tmp;
+ // tdf#89665: don't use operator[] to write - too slow!
+ // interestingly gcc 4.9 -Os won't even inline the const operator[]
+ sal_Int32 const*const pFrom(off[from].getConstArray());
+ sal_Int32 *const pTo(off[to].getArray());
for (sal_Int32 j = 0; j < nCount; j++)
- off[to][j] = off[from][off[to][j]];
+ {
+ assert(pTo[j] < off[from].getLength());
+ pTo[j] = pFrom[pTo[j]];
+ }
}
offset = off[to];
return tmpStr;