sc/inc/cellvalue.hxx              |    2 ++
 sc/source/core/data/cellvalue.cxx |   20 ++++++++++++++++++++
 sc/source/core/data/column3.cxx   |   28 ++++++++++++++++++++++++----
 3 files changed, 46 insertions(+), 4 deletions(-)

New commits:
commit e7fe6c626ee8c8fe97f2af95b62d58643e478bb4
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Nov 1 11:39:58 2024 +0200
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Nov 24 01:01:14 2024 +0100

    tdf#163667 speed up spreadsheet with lots of cond formatting
    
    Attempt to avoid the cost of GetCondResult when dealing with large runs
    of identical cells
    
    Change-Id: If9192a9858e6785263ea1621e98d1b1d5de74c4c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175909
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit 7d7d94b7713d86e2fd972c3b81845eaffb5761e5)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175898
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    (cherry picked from commit 2c280a6de9cba0ba0cc9f1ae2ee120c0011eca09)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175983
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx
index d5a29c607c90..f1e74ef96fa6 100644
--- a/sc/inc/cellvalue.hxx
+++ b/sc/inc/cellvalue.hxx
@@ -128,6 +128,8 @@ public:
     SC_DLLPUBLIC ScRefCellValue( ScDocument& rDoc, const ScAddress& rPos );
     SC_DLLPUBLIC ScRefCellValue( ScDocument& rDoc, const ScAddress& rPos, 
sc::ColumnBlockPosition& rBlockPos );
 
+    bool operator==(const ScRefCellValue&) const;
+
     void clear();
 
     CellType getType() const { return meType; }
diff --git a/sc/source/core/data/cellvalue.cxx 
b/sc/source/core/data/cellvalue.cxx
index 4330ea972992..b74b841a988f 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -685,4 +685,24 @@ bool ScRefCellValue::equalsWithoutFormat( const 
ScRefCellValue& r ) const
     return equalsWithoutFormatImpl(*this, r);
 }
 
+bool ScRefCellValue::operator==( const ScRefCellValue& r ) const
+{
+    if (meType != r.meType)
+        return false;
+
+    switch (meType)
+    {
+        case CELLTYPE_NONE:
+            return true;
+        case CELLTYPE_VALUE:
+            return mfValue == r.mfValue;
+        case CELLTYPE_STRING:
+            return mpString == r.mpString;
+        case CELLTYPE_FORMULA:
+            return equalsFormulaCells(getFormula(), r.getFormula());
+        default:
+            return false;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index e0f5006f0d63..32348d8bd134 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2721,26 +2721,44 @@ void ScColumn::GetBackColorFilterEntries(SCROW nRow1, 
SCROW nRow2, ScFilterEntri
         return;
 
     ScAddress aCell(GetCol(), 0, GetTab());
+    ScDocument& rDoc = GetDoc();
+    const ScPatternAttr* pPrevPattern = nullptr;
+    ScRefCellValue aPrevCellValue;
     while (nRow1 <= nRow2)
     {
         aCell.SetRow(nRow1);
 
         Color aBackColor;
         bool bCondBackColor = false;
+        const ScPatternAttr* pPattern = rDoc.GetPattern(aCell.Col(), 
aCell.Row(), aCell.Tab());
+        ScConditionalFormat* pCondFormat = rDoc.GetCondFormat(aCell.Col(), 
aCell.Row(), aCell.Tab());
 
-        const ScPatternAttr* pPattern = GetDoc().GetPattern(aCell.Col(), 
aCell.Row(), aCell.Tab());
         if (pPattern)
         {
+            // Speed up processing when dealing with runs of identical cells. 
We only
+            // care about collecting unique colors, so no need to process a 
cell if the result
+            // will be the same as the previous cell.
+            // Which we can only do if there is no conditional format to 
override the color on this cell.
+            if (!pCondFormat)
+            {
+                ScRefCellValue aCellValue = GetCellValue(nRow1);
+                if (pPrevPattern == pPattern && aCellValue == aPrevCellValue)
+                {
+                    nRow1++;
+                    continue;
+                }
+                aPrevCellValue = aCellValue;
+                pPrevPattern = pPattern;
+            }
             if 
(!pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData().empty())
             {
-                const SfxItemSet* pCondSet = GetDoc().GetCondResult(GetCol(), 
nRow1, GetTab());
+                const SfxItemSet* pCondSet = rDoc.GetCondResult(GetCol(), 
nRow1, GetTab());
                 const SvxBrushItem* pBrush = 
&pPattern->GetItem(ATTR_BACKGROUND, pCondSet);
                 aBackColor = pBrush->GetColor();
                 bCondBackColor = true;
             }
         }
 
-        ScConditionalFormat* pCondFormat = GetDoc().GetCondFormat(aCell.Col(), 
aCell.Row(), aCell.Tab());
         if (pCondFormat)
         {
             for (size_t nFormat = 0; nFormat < pCondFormat->size(); nFormat++)
@@ -2754,6 +2772,8 @@ void ScColumn::GetBackColorFilterEntries(SCROW nRow1, 
SCROW nRow2, ScFilterEntri
                     {
                         aBackColor = *oColor;
                         bCondBackColor = true;
+                        // we are overriding the color, so we need to clear 
the one-item cache.
+                        pPrevPattern = nullptr;
                     }
                 }
             }
@@ -2761,7 +2781,7 @@ void ScColumn::GetBackColorFilterEntries(SCROW nRow1, 
SCROW nRow2, ScFilterEntri
 
         if (!bCondBackColor)
         {
-            const SvxBrushItem* pBrush = GetDoc().GetAttr(aCell, 
ATTR_BACKGROUND);
+            const SvxBrushItem* pBrush = rDoc.GetAttr(aCell, ATTR_BACKGROUND);
             aBackColor = pBrush->GetColor();
         }
 

Reply via email to