sc/qa/unit/ucalc_formula.cxx | 2 +- sc/source/core/tool/compiler.cxx | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-)
New commits: commit faea4bf55e4160565da6b307e6799312f677bee9 Author: Balazs Varga <balazs.varga.ext...@allotropia.de> AuthorDate: Wed Mar 20 18:32:44 2024 +0100 Commit: Balazs Varga <balazs.varga.ext...@allotropia.de> CommitDate: Mon Mar 25 08:48:35 2024 +0100 tdf#159687 sc formula SUMPRODUCT performance fix: add more binary operators which need to be checked if they are next to a trimmable DoubleRef arguments or not. Example: =SUMPRODUCT(($D:$D>M47:M47)*($D:$D<M48:M48)*($I:$I=N$41)) --> $D:$D and $I:$I columns are trimmable. Recalculation of formulas with a lot of SUMPRODUCT where we comparing full columns could take minutes during editing a sheet. With reducing the size of the compared ranges to the actual data could significantly speed up the recalculation. This takes the recalculation time from ~50 sec to <1 sec on my machine. Note: probabaly the same could be applied to the SUM function. Change-Id: I758660d0b638ef7255bd5a41a96755289b5a2b41 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165074 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Reviewed-by: Balazs Varga <balazs.varga.ext...@allotropia.de> diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index feb0e8fef22a..153096d6a434 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -1464,7 +1464,7 @@ CPPUNIT_TEST_FIXTURE(TestFormula, testFormulaAnnotateTrimOnDoubleRefs) { "=SUMPRODUCT(A:A=$C$1; 1-(A:A=$C$1))", - ScRange(-1, -1, -1, -1, -1, -1), // Has no trimmable double-ref. + ScRange(0, 0, 0, 0, 1048575, 0), 0.0, false // Not in matrix mode. }, diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index f5805db887c9..13fed4ac95b3 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -6568,6 +6568,8 @@ void ScCompiler::AnnotateTrimOnDoubleRefs() // such that one of the operands of ocEqual is a double-ref. // Examples of formula that matches this are: // SUMPRODUCT(IF($A:$A=$L12;$D:$D*G:G)) + // Also in case of DoubleRef arguments around other Binary operators can be trimmable: + // SUMPRODUCT(($D:$D>M47:M47)*($D:$D<M48:M48)*($I:$I=N$41)) bool bTillClose = true; bool bCloseTillIf = false; sal_Int16 nToksTillIf = 0; @@ -6601,6 +6603,39 @@ void ScCompiler::AnnotateTrimOnDoubleRefs() } } break; + case ocEqual: + case ocAdd: + case ocSub: + case ocAmpersand: + case ocPow: + case ocNotEqual: + case ocLess: + case ocGreater: + case ocLessEqual: + case ocGreaterEqual: + case ocAnd: + case ocOr: + case ocXor: + case ocIntersect: + case ocUnion: + case ocRange: + { + if (!pTok->IsInForceArray()) + break; + FormulaToken* pLHS = *(ppTok - 1); + FormulaToken* pRHS = *(ppTok - 2); + StackVar lhsType = pLHS->GetType(); + StackVar rhsType = pRHS->GetType(); + if (lhsType == svDoubleRef && (rhsType == svSingleRef || rhsType == svDoubleRef)) + { + pLHS->GetDoubleRef()->SetTrimToData(true); + } + if (rhsType == svDoubleRef && (lhsType == svSingleRef || lhsType == svDoubleRef)) + { + pRHS->GetDoubleRef()->SetTrimToData(true); + } + } + break; case ocPush: break; case ocClose: