vcl/source/gdi/CommonSalLayout.cxx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
New commits: commit baf6c57496fe38c5ee4ab34829aaf4d4d6598d28 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Tue Mar 15 08:45:59 2022 +0100 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Tue Mar 15 14:39:03 2022 +0100 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.lu...@collabora.com> Tested-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index e26dc68692bf..c4217e21a985 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()) {