summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <laszlo.nemeth@collabora.com>2015-02-10 10:25:13 +0100
committerLászló Németh <laszlo.nemeth@collabora.com>2015-02-10 11:10:58 +0100
commitb18b5b7edf3d14ef5f0efe53e367f88a423088c4 (patch)
tree91cd749ab7baf6bf1e46616d1c727fe8e599e0c4
parent615fae2f67028f3c5c51c70c77dbaa9b9f3856d6 (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.hxx2
-rw-r--r--sc/source/core/tool/token.cxx40
-rw-r--r--sc/source/filter/excel/excform.cxx9
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);