diff options
author | Michael Stahl <mstahl@redhat.com> | 2015-02-20 20:57:59 +0100 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2015-02-26 19:12:44 +0000 |
commit | d1057d2fc205dc47d845b3e5738a54c68824e90b (patch) | |
tree | ee093517c9cc20a4aca069e1177349463f990d63 | |
parent | bddab9a94f84e4067ca268c67df1b8708d3eea23 (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/14643
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Eike Rathke <erack@redhat.com>
-rw-r--r-- | i18npool/source/transliteration/transliterationImpl.cxx | 10 |
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; |