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
This commit is contained in:
parent
615fae2f67
commit
b18b5b7edf
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user