Kaydet (Commit) deaac6ff authored tarafından Daniel Bankston's avatar Daniel Bankston Kaydeden (comit) Kohei Yoshida

Improve matrix import performance.

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.

This commit prevent that from happening, which gives us back our performance.

Change-Id: I961f69b0117d4261f8afefb6d94173105f0925b2
üst 1b40fbe4
...@@ -376,7 +376,7 @@ public: ...@@ -376,7 +376,7 @@ public:
void GetFormula( rtl::OUStringBuffer& rBuffer, void GetFormula( rtl::OUStringBuffer& rBuffer,
const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const; const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
void SetDirty(); void SetDirty( bool bDirtyFlag=true );
void SetDirtyVar(); void SetDirtyVar();
// If setting entire document dirty after load, no broadcasts but still append to FormulaTree. // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
void SetDirtyAfterLoad(); void SetDirtyAfterLoad();
...@@ -472,7 +472,7 @@ public: ...@@ -472,7 +472,7 @@ public:
virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint); virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint);
void SetCompile( bool bVal ) { bCompile = bVal; } void SetCompile( bool bVal ) { bCompile = bVal; }
ScDocument* GetDocument() const { return pDocument; } ScDocument* GetDocument() const { return pDocument; }
void SetMatColsRows( SCCOL nCols, SCROW nRows ); void SetMatColsRows( SCCOL nCols, SCROW nRows, bool bDirtyFlag=true );
void GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const; void GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
// cell belongs to ChangeTrack and not to the real document // cell belongs to ChangeTrack and not to the real document
......
...@@ -770,7 +770,8 @@ public: ...@@ -770,7 +770,8 @@ public:
const ScMarkData& rMark, const ScMarkData& rMark,
const rtl::OUString& rFormula, const rtl::OUString& rFormula,
const ScTokenArray* p = NULL, const ScTokenArray* p = NULL,
const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ); const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
bool bDirtyFlag=true );
SC_DLLPUBLIC void InsertTableOp(const ScTabOpParam& rParam, // multi-operation SC_DLLPUBLIC void InsertTableOp(const ScTabOpParam& rParam, // multi-operation
SCCOL nCol1, SCROW nRow1, SCCOL nCol1, SCROW nRow1,
SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark); SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark);
...@@ -1657,7 +1658,8 @@ public: ...@@ -1657,7 +1658,8 @@ public:
void PutInFormulaTree( ScFormulaCell* pCell ); void PutInFormulaTree( ScFormulaCell* pCell );
void RemoveFromFormulaTree( ScFormulaCell* pCell ); void RemoveFromFormulaTree( ScFormulaCell* pCell );
void CalcFormulaTree( bool bOnlyForced = false, void CalcFormulaTree( bool bOnlyForced = false,
bool bNoProgressBar = false ); bool bNoProgressBar = false,
bool bDirtyFlag=true );
void ClearFormulaTree(); void ClearFormulaTree();
void AppendToFormulaTrack( ScFormulaCell* pCell ); void AppendToFormulaTrack( ScFormulaCell* pCell );
void RemoveFromFormulaTrack( ScFormulaCell* pCell ); void RemoveFromFormulaTrack( ScFormulaCell* pCell );
......
...@@ -1726,17 +1726,17 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam ) ...@@ -1726,17 +1726,17 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
} }
void ScFormulaCell::SetMatColsRows( SCCOL nCols, SCROW nRows ) void ScFormulaCell::SetMatColsRows( SCCOL nCols, SCROW nRows, bool bDirtyFlag )
{ {
ScMatrixFormulaCellToken* pMat = aResult.GetMatrixFormulaCellTokenNonConst(); ScMatrixFormulaCellToken* pMat = aResult.GetMatrixFormulaCellTokenNonConst();
if (pMat) if (pMat)
pMat->SetMatColsRows( nCols, nRows); pMat->SetMatColsRows( nCols, nRows );
else if (nCols || nRows) else if (nCols || nRows)
{ {
aResult.SetToken( new ScMatrixFormulaCellToken( nCols, nRows)); aResult.SetToken( new ScMatrixFormulaCellToken( nCols, nRows));
// Setting the new token actually forces an empty result at this top // Setting the new token actually forces an empty result at this top
// left cell, so have that recalculated. // left cell, so have that recalculated.
SetDirty(); SetDirty( bDirtyFlag );
} }
} }
...@@ -1805,7 +1805,7 @@ void ScFormulaCell::Notify( SvtBroadcaster&, const SfxHint& rHint) ...@@ -1805,7 +1805,7 @@ void ScFormulaCell::Notify( SvtBroadcaster&, const SfxHint& rHint)
} }
} }
void ScFormulaCell::SetDirty() void ScFormulaCell::SetDirty( bool bDirtyFlag )
{ {
if ( !IsInChangeTrack() ) if ( !IsInChangeTrack() )
{ {
...@@ -1819,7 +1819,8 @@ void ScFormulaCell::SetDirty() ...@@ -1819,7 +1819,8 @@ void ScFormulaCell::SetDirty()
// setzen, z.B. in CompileTokenArray // setzen, z.B. in CompileTokenArray
if ( !bDirty || !pDocument->IsInFormulaTree( this ) ) if ( !bDirty || !pDocument->IsInFormulaTree( this ) )
{ {
SetDirtyVar(); if( bDirtyFlag )
SetDirtyVar();
pDocument->AppendToFormulaTrack( this ); pDocument->AppendToFormulaTrack( this );
pDocument->TrackFormulas(); pDocument->TrackFormulas();
} }
......
...@@ -122,7 +122,8 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1, ...@@ -122,7 +122,8 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
const ScMarkData& rMark, const ScMarkData& rMark,
const rtl::OUString& rFormula, const rtl::OUString& rFormula,
const ScTokenArray* pArr, const ScTokenArray* pArr,
const formula::FormulaGrammar::Grammar eGram ) const formula::FormulaGrammar::Grammar eGram,
bool bDirtyFlag )
{ {
PutInOrder(nCol1, nCol2); PutInOrder(nCol1, nCol2);
PutInOrder(nRow1, nRow2); PutInOrder(nRow1, nRow2);
...@@ -155,7 +156,7 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1, ...@@ -155,7 +156,7 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
pCell = new ScFormulaCell( this, aPos, pArr, eGram, MM_FORMULA ); pCell = new ScFormulaCell( this, aPos, pArr, eGram, MM_FORMULA );
else else
pCell = new ScFormulaCell( this, aPos, rFormula, eGram, MM_FORMULA ); 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, bDirtyFlag );
itr = rMark.begin(); itr = rMark.begin();
for (; itr != itrEnd && *itr < nMax; ++itr) for (; itr != itrEnd && *itr < nMax; ++itr)
{ {
......
...@@ -280,7 +280,7 @@ bool ScDocument::IsInFormulaTree( ScFormulaCell* pCell ) const ...@@ -280,7 +280,7 @@ bool ScDocument::IsInFormulaTree( ScFormulaCell* pCell ) const
} }
void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bNoProgress ) void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bNoProgress, bool bDirtyFlag )
{ {
OSL_ENSURE( !IsCalculatingFormulaTree(), "CalcFormulaTree recursion" ); OSL_ENSURE( !IsCalculatingFormulaTree(), "CalcFormulaTree recursion" );
// never ever recurse into this, might end up lost in infinity // never ever recurse into this, might end up lost in infinity
...@@ -317,7 +317,8 @@ void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bNoProgress ) ...@@ -317,7 +317,8 @@ void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bNoProgress )
} }
else else
{ // andere simpel berechnen { // andere simpel berechnen
pCell->SetDirtyVar(); if( bDirtyFlag )
pCell->SetDirtyVar();
pCell = pCell->GetNext(); pCell = pCell->GetNext();
} }
} }
......
...@@ -297,7 +297,7 @@ void ScMyTables::AddMatrixRange( ...@@ -297,7 +297,7 @@ void ScMyTables::AddMatrixRange(
pDoc->InsertMatrixFormula( pDoc->InsertMatrixFormula(
aScRange.aStart.Col(), aScRange.aStart.Row(), aScRange.aStart.Col(), aScRange.aStart.Row(),
aScRange.aEnd.Col(), aScRange.aEnd.Row(), aScRange.aEnd.Col(), aScRange.aEnd.Row(),
aMark, EMPTY_STRING, pCode, eGrammar ); aMark, EMPTY_STRING, pCode, eGrammar, false );
delete pCode; delete pCode;
pDoc->IncXMLImportedFormulaCount( rFormula.getLength() ); pDoc->IncXMLImportedFormulaCount( rFormula.getLength() );
} }
......
...@@ -441,7 +441,7 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un ...@@ -441,7 +441,7 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
if(sGenerator.indexOf(SC_LIBO_PROD_NAME) == -1) if(sGenerator.indexOf(SC_LIBO_PROD_NAME) == -1)
DoHardRecalc(false); DoHardRecalc(false);
else //still need to recalc volatile formula cells else //still need to recalc volatile formula cells
DoRecalc(false); aDocument.CalcFormulaTree(false, false, false);
aDocument.EnableAdjustHeight(false); aDocument.EnableAdjustHeight(false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment