faster comparison of very long strings (tdf#147284)
Comparing long string backwards is inefficient because forward
compare has better memory prefetch. For the PDF export
of the document this drops the comparison cost to 1% from 6%.
Change-Id: Ide29608bf56915cc528e6ec8b98ccf8ebf4693a9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131579
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Tested-by: Luboš Luňák <l.lunak@collabora.com>
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index e26dc68..c4217e2 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -167,11 +167,27 @@ struct FirstCharsStringHash
}
};
struct ForwardStringCompareEqual
{
bool operator()( const OUString& str1, const OUString& str2 ) const
{
// Strings passed to GenericSalLayout::CreateTextLayoutCache() may be very long,
// and OUString operator == compares backwards, which is inefficient for very long
// strings (bad memory prefetch).
if( str1.getLength() != str2.getLength())
return false;
if( str1.getStr() == str2.getStr())
return true;
return memcmp( str1.getStr(), str2.getStr(), str1.getLength() * sizeof( str1.getStr()[ 0 ] )) == 0;
}
};
} // namespace
std::shared_ptr<const vcl::text::TextLayoutCache> GenericSalLayout::CreateTextLayoutCache(OUString const& rString)
{
typedef o3tl::lru_map<OUString, std::shared_ptr<const vcl::text::TextLayoutCache>, FirstCharsStringHash> Cache;
typedef o3tl::lru_map<OUString, std::shared_ptr<const vcl::text::TextLayoutCache>,
FirstCharsStringHash, ForwardStringCompareEqual> Cache;
static vcl::DeleteOnDeinit< Cache > cache( 1000 );
if( Cache* map = cache.get())
{