Hi, Kohei and Markus,
Our latest changes that recalculate volatile formulas at the end of
import resulted in several seconds performance loss on a large matrix
test file with complex formulas.
When the matrix cells are put in the document, ScFormulaCell::SetDirty()
gets called. Although the cells are set clean during import after this,
SetDirty() also uses ScDocument::TrackFormulas() which puts the cells in
the formula tree. So when we call ScDocument::DoRecalc() at the end of
import, the interpreter goes through all matrix cells because they are
in the formula tree.
My changes in the attached diff prevent this from happening, which gives
us back our performance. Is this approach ok?
Respectfully,
Daniel Bankston
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 9499084..9f55491 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -474,7 +474,7 @@ public:
virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint);
void SetCompile( bool bVal ) { bCompile = bVal; }
ScDocument* GetDocument() const { return pDocument; }
- void SetMatColsRows( SCCOL nCols, SCROW nRows );
+ void SetMatColsRows( SCCOL nCols, SCROW nRows, bool bSetDirty=true );
void GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
// cell belongs to ChangeTrack and not to the real document
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 9a0c167..0503f2c 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -775,7 +775,8 @@ public:
const ScMarkData& rMark,
const rtl::OUString& rFormula,
const ScTokenArray* p = NULL,
- const formula::FormulaGrammar::Grammar =
formula::FormulaGrammar::GRAM_DEFAULT );
+ const formula::FormulaGrammar::Grammar =
formula::FormulaGrammar::GRAM_DEFAULT,
+ bool bSetDirty=true );
SC_DLLPUBLIC void InsertTableOp(const ScTabOpParam& rParam, // multi-operation
SCCOL nCol1, SCROW nRow1,
SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark);
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 421f401..886e68b 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1728,7 +1728,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
}
-void ScFormulaCell::SetMatColsRows( SCCOL nCols, SCROW nRows )
+void ScFormulaCell::SetMatColsRows( SCCOL nCols, SCROW nRows, bool bSetDirty )
{
ScMatrixFormulaCellToken* pMat = aResult.GetMatrixFormulaCellTokenNonConst();
if (pMat)
@@ -1738,7 +1738,10 @@ void ScFormulaCell::SetMatColsRows( SCCOL nCols, SCROW nRows )
aResult.SetToken( new ScMatrixFormulaCellToken( nCols, nRows));
// Setting the new token actually forces an empty result at this top
// left cell, so have that recalculated.
- SetDirty();
+ //but during ODS import, we don't won't matrix cells to be dirty
+ //or added to the formula tree so we check bSetDirty.
+ if(bSetDirty)
+ SetDirty();
}
}
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 8eca485..7411ffa 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -123,7 +123,8 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
const ScMarkData& rMark,
const rtl::OUString& rFormula,
const ScTokenArray* pArr,
- const formula::FormulaGrammar::Grammar eGram )
+ const formula::FormulaGrammar::Grammar eGram,
+ bool bSetDirty )
{
PutInOrder(nCol1, nCol2);
PutInOrder(nRow1, nRow2);
@@ -157,7 +158,7 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
pCell = new ScFormulaCell( this, aPos, pArr, eGram, MM_FORMULA );
else
pCell = new ScFormulaCell( this, aPos, rFormula, eGram, MM_FORMULA );
- pCell->SetMatColsRows( nCol2 - nCol1 + 1, nRow2 - nRow1 + 1 );
+ pCell->SetMatColsRows( nCol2 - nCol1 + 1, nRow2 - nRow1 + 1, bSetDirty );
itr = rMark.begin();
for (; itr != itrEnd && *itr < nMax; ++itr)
{
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index c5a5eeb..f5ee5be 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -297,7 +297,7 @@ void ScMyTables::AddMatrixRange(
pDoc->InsertMatrixFormula(
aScRange.aStart.Col(), aScRange.aStart.Row(),
aScRange.aEnd.Col(), aScRange.aEnd.Row(),
- aMark, EMPTY_STRING, pCode, eGrammar );
+ aMark, EMPTY_STRING, pCode, eGrammar, false );
delete pCode;
pDoc->IncXMLImportedFormulaCount( rFormula.getLength() );
}
Context
- [GSOC] Fix for performance loss due to recalc of volatile cells · Daniel Bankston
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.