summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBalazs Varga <balazs.varga.extern@allotropia.de>2024-03-20 18:32:44 +0100
committerThorsten Behrens <thorsten.behrens@allotropia.de>2024-04-30 13:07:23 +0200
commit47b0c33eb0e4defda6f2e8c3eb143f1345cdc1b9 (patch)
tree28d62867898e458b40fc167ac9d1d45dfd8c56ec
parenttdf#159456 - chart view: fix wrongly shifted value Y axis (diff)
downloadcore-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.cxx2
-rw-r--r--sc/source/core/tool/compiler.cxx35
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: