diff options
author | Balazs Varga <balazs.varga.extern@allotropia.de> | 2024-03-20 18:32:44 +0100 |
---|---|---|
committer | Thorsten Behrens <thorsten.behrens@allotropia.de> | 2024-04-30 13:07:23 +0200 |
commit | 47b0c33eb0e4defda6f2e8c3eb143f1345cdc1b9 (patch) | |
tree | 28d62867898e458b40fc167ac9d1d45dfd8c56ec | |
parent | tdf#159456 - chart view: fix wrongly shifted value Y axis (diff) | |
download | core-47b0c33eb0e4defda6f2e8c3eb143f1345cdc1b9.tar.gz core-47b0c33eb0e4defda6f2e8c3eb143f1345cdc1b9.zip |
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.grandin@collabora.co.uk>
Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de>
-rw-r--r-- | sc/qa/unit/ucalc_formula.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/compiler.cxx | 35 |
2 files changed, 36 insertions, 1 deletions
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 c9934c26fff6..451956922c29 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -6569,6 +6569,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; @@ -6602,6 +6604,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: |