diff options
author | László Németh <laszlo.nemeth@collabora.com> | 2015-02-10 10:25:13 +0100 |
---|---|---|
committer | László Németh <laszlo.nemeth@collabora.com> | 2015-02-10 11:10:58 +0100 |
commit | b18b5b7edf3d14ef5f0efe53e367f88a423088c4 (patch) | |
tree | 91cd749ab7baf6bf1e46616d1c727fe8e599e0c4 | |
parent | 615fae2f67028f3c5c51c70c77dbaa9b9f3856d6 (diff) |
tdf#89281 fix performance regression of XLS import
The fix for Bug 76611 caused ~20% performance loss in XLS import.
With optional cloning of ScTokenArray of the shared XLS formulas
depending on the need of address wrapping, it is possible to gain
back near the original performance.
Note: The original patch for Bug 76611 has already got an unit test,
too (see wrapped-refs.xls), and that unit test works with this
improved patch, too.
Change-Id: Ibfb59d1543ef9c4b8a075d5c4e37f77ab451aaa0
-rw-r--r-- | sc/inc/tokenarray.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 40 | ||||
-rw-r--r-- | sc/source/filter/excel/excform.cxx | 9 |
3 files changed, 38 insertions, 13 deletions
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index ab1e9419042b..d1a4bed9d879 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -239,7 +239,7 @@ public: */ OUString CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const; - void WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow ); + bool WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow, bool bQueryNeedWrap = false); #if DEBUG_FORMULA_COMPILER void Dump() const; diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index e7e6ecefd420..563b2007b28d 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -3994,17 +3994,27 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre namespace { -void wrapAddress( ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow ) +bool wrapAddress( ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow, bool bQueryOnly ) { + bool bChanged = false; if (rPos.Col() > nMaxCol) - rPos.SetCol(rPos.Col() - nMaxCol - 1); + { + if (!bQueryOnly) + rPos.SetCol(rPos.Col() - nMaxCol - 1); + bChanged = true; + } if (rPos.Row() > nMaxRow) - rPos.SetRow(rPos.Row() - nMaxRow - 1); + { + if (!bQueryOnly) + rPos.SetRow(rPos.Row() - nMaxRow - 1); + bChanged = true; + } + return bChanged; } } -void ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow ) +bool ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow, bool bQueryNeedWrap) { FormulaToken** p = pCode; FormulaToken** pEnd = p + static_cast<size_t>(nLen); @@ -4017,8 +4027,12 @@ void ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nM formula::FormulaToken* pToken = *p; ScSingleRefData& rRef = *pToken->GetSingleRef(); ScAddress aAbs = rRef.toAbs(rPos); - wrapAddress(aAbs, nMaxCol, nMaxRow); - rRef.SetAddress(aAbs, rPos); + if (wrapAddress(aAbs, nMaxCol, nMaxRow, bQueryNeedWrap)) + { + if (bQueryNeedWrap) + return true; + rRef.SetAddress(aAbs, rPos); + } } break; case svDoubleRef: @@ -4026,16 +4040,22 @@ void ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nM formula::FormulaToken* pToken = *p; ScComplexRefData& rRef = *pToken->GetDoubleRef(); ScRange aAbs = rRef.toAbs(rPos); - wrapAddress(aAbs.aStart, nMaxCol, nMaxRow); - wrapAddress(aAbs.aEnd, nMaxCol, nMaxRow); - aAbs.PutInOrder(); - rRef.SetRange(aAbs, rPos); + bool bChanged = wrapAddress(aAbs.aStart, nMaxCol, nMaxRow, bQueryNeedWrap); + bool bChanged2 = wrapAddress(aAbs.aEnd, nMaxCol, nMaxRow, bQueryNeedWrap); + if (bChanged || bChanged2) + { + if (bQueryNeedWrap) + return true; + aAbs.PutInOrder(); + rRef.SetRange(aAbs, rPos); + } } break; default: ; } } + return false; } #if DEBUG_FORMULA_COMPILER diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx index 22becd6c5031..dec9a8165e32 100644 --- a/sc/source/filter/excel/excform.cxx +++ b/sc/source/filter/excel/excform.cxx @@ -122,8 +122,13 @@ void ImportExcel::Formula( const ScTokenArray* pSharedCode = pFormConv->GetSharedFormula(aRefPos); if (pSharedCode) { - ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, pSharedCode->Clone()); - pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8); + ScFormulaCell* pCell = new ScFormulaCell(pD, aScPos, *pSharedCode); + // Do we need to wrap the column or row indices? (tdf#76611) + if (pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8, true)) + { + pCell = new ScFormulaCell(pD, aScPos, pSharedCode->Clone()); + pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8); + } rDoc.getDoc().EnsureTable(aScPos.Tab()); rDoc.setFormulaCell(aScPos, pCell); pCell->SetNeedNumberFormat(false); |