sc/inc/document.hxx              |    1 +
 sc/source/core/data/documen4.cxx |   27 ++++++++++++++++++++-------
 2 files changed, 21 insertions(+), 7 deletions(-)

New commits:
commit 3fec0ddc677227ebcc1183028f551e82972791a5
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Wed May 21 20:29:30 2025 +0200
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Sun Jun 15 22:51:39 2025 +0200

    tdf#166684 avoid O(n^2) loop in ScDocument::AddValidationEntry
    
    during XLSX import. Shaves 30% off load time for this document.
    The downside is that we might get a few duplicate entries,
    which (a) is rare, excel seems to mostly deduplicate these
    and (b) is not crucial for correct functioning for us.
    
    Change-Id: I7a95f4c790dd195c04c9de1f2700981d3e318731
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185650
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    (cherry picked from commit 04986d105a2b81a2b549d722541f5aa3a04f3937)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185738
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 0dfa4d1030c1..084df66beb18 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -414,6 +414,7 @@ private:
     std::unique_ptr<ScDrawLayer> mpDrawLayer;           // SdrModel
     rtl::Reference<XColorList> pColorList;
     std::unique_ptr<ScValidationDataList> pValidationList;              // 
validity
+    sal_uInt32 mnLastValidationListMax = 0;
     SvNumberFormatterIndexTable* pFormatExchangeList;    // for application of 
number formats
     TableContainer maTabs;
     rtl::Reference<ScSheetLimits> mxSheetLimits;
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index f86fedc4b472..af2044861f36 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -715,17 +715,30 @@ sal_uInt32 ScDocument::AddValidationEntry( const 
ScValidationData& rNew )
     {
         ScMutationGuard aGuard(*this, ScMutationGuardFlags::CORE);
         pValidationList.reset(new ScValidationDataList);
+        mnLastValidationListMax = 0;
     }
 
     sal_uInt32 nMax = 0;
-    for( const auto& rxData : *pValidationList )
+    if (IsImportingXLSX())
     {
-        const ScValidationData* pData = rxData.get();
-        sal_uInt32 nKey = pData->GetKey();
-        if ( pData->EqualEntries( rNew ) )
-            return nKey;
-        if ( nKey > nMax )
-            nMax = nKey;
+        // During import, the search becomes an O(n^2) problem.
+        // Just ignore any duplicates we might find, which seems to be rare.
+        nMax = mnLastValidationListMax;
+        ++mnLastValidationListMax;
+    }
+    else
+    {
+        for( const auto& rxData : *pValidationList )
+        {
+            const ScValidationData* pData = rxData.get();
+            sal_uInt32 nKey = pData->GetKey();
+            if ( pData->EqualEntries( rNew ) )
+            {
+                return nKey;
+            }
+            if ( nKey > nMax )
+                nMax = nKey;
+        }
     }
 
     // might be called from ScPatternAttr::MigrateToDocument; thus clone (real 
copy)

Reply via email to