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() );
 }
_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice

Reply via email to