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(); }