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())
     {

Reply via email to