Kaydet (Commit) 7ba5f709 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Pass contiguous cell data as an array to matrix. This is faster.

It's generally faster to pass an array of elements to matrix than
passing them individually.

Change-Id: I4502025d08040327c1d1c09ce1756928be054c25
üst ed5d2c65
......@@ -261,9 +261,14 @@ public:
void PutDouble( double fVal, SCSIZE nC, SCSIZE nR);
void PutDouble( double fVal, SCSIZE nIndex);
void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
void PutString( const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR);
void PutString( const ::rtl::OUString& rStr, SCSIZE nIndex);
void PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
void PutEmpty( SCSIZE nC, SCSIZE nR);
/// Jump FALSE without path
void PutEmptyPath( SCSIZE nC, SCSIZE nR);
void PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR );
......
......@@ -351,6 +351,43 @@ ScInterpreter::VolatileType ScInterpreter::GetVolatileType() const
return meVolatileType;
}
namespace {
struct CellBucket
{
SCSIZE mnNumValStart;
SCSIZE mnStrValStart;
std::vector<double> maNumVals;
std::vector<rtl::OUString> maStrVals;
CellBucket() : mnNumValStart(0), mnStrValStart(0) {}
void flush(ScMatrix& rMat, SCSIZE nCol)
{
if (!maNumVals.empty())
{
const double* p = &maNumVals[0];
rMat.PutDouble(p, maNumVals.size(), nCol, mnNumValStart);
reset();
}
else if (!maStrVals.empty())
{
const rtl::OUString* p = &maStrVals[0];
rMat.PutString(p, maStrVals.size(), nCol, mnStrValStart);
reset();
}
}
void reset()
{
mnNumValStart = mnStrValStart = 0;
maNumVals.clear();
maStrVals.clear();
}
};
}
ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken,
SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
......@@ -382,46 +419,89 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
if (!pMat || nGlobalError)
return NULL;
ScCellIterator aCellIter(
pDok, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
CellBucket aBucket;
for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell =
aCellIter.GetNext())
for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
{
SCCOL nThisCol = aCellIter.GetCol();
SCROW nThisRow = aCellIter.GetRow();
if (HasCellEmptyData(pCell))
continue;
// Scan one column at a time, to pass a sequence of values to matrix in one call.
ScCellIterator aCellIter(
pDok, nCol, nRow1, nTab1, nCol, nRow2, nTab2);
SCROW nPrevRow = -2, nThisRow = -2;
if (HasCellValueData(pCell))
for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext(), nPrevRow = nThisRow)
{
ScAddress aAdr( nThisCol, nThisRow, nTab1);
double fVal = GetCellValue( aAdr, pCell);
nThisRow = aCellIter.GetRow();
if (HasCellEmptyData(pCell))
{
aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
continue;
}
if (HasCellValueData(pCell))
{
ScAddress aAdr(nCol, nThisRow, nTab1);
double fVal = GetCellValue( aAdr, pCell);
if ( nGlobalError )
{
fVal = CreateDoubleError( nGlobalError);
nGlobalError = 0;
}
if (nThisRow == nPrevRow + 1)
{
// Secondary numbers.
aBucket.maNumVals.push_back(fVal);
}
else
{
// First number.
aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
aBucket.mnNumValStart = nThisRow - nRow1;
aBucket.maNumVals.push_back(fVal);
}
continue;
}
String aStr;
GetCellString( aStr, pCell);
if ( nGlobalError )
{
fVal = CreateDoubleError( nGlobalError);
double fVal = CreateDoubleError( nGlobalError);
nGlobalError = 0;
if (nThisRow == nPrevRow + 1)
{
// Secondary numbers.
aBucket.maNumVals.push_back(fVal);
}
else
{
// First number.
aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
aBucket.mnNumValStart = nThisRow - nRow1;
aBucket.maNumVals.push_back(fVal);
}
}
else
{
if (nThisRow == nPrevRow + 1)
{
// Secondary numbers.
aBucket.maStrVals.push_back(aStr);
}
else
{
// First number.
aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
aBucket.mnStrValStart = nThisRow - nRow1;
aBucket.maStrVals.push_back(aStr);
}
}
pMat->PutDouble( fVal,
static_cast<SCSIZE>(nThisCol-nCol1),
static_cast<SCSIZE>(nThisRow-nRow1));
continue;
}
String aStr;
GetCellString( aStr, pCell);
if ( nGlobalError )
{
double fVal = CreateDoubleError( nGlobalError);
nGlobalError = 0;
pMat->PutDouble( fVal,
static_cast<SCSIZE>(nThisCol-nCol1),
static_cast<SCSIZE>(nThisRow-nRow1));
}
else
pMat->PutString( aStr,
static_cast<SCSIZE>(nThisCol-nCol1),
static_cast<SCSIZE>(nThisRow-nRow1));
aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
}
if (pTokenMatrixMap)
......
......@@ -343,10 +343,14 @@ public:
bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const;
bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const;
void SetErrorAtInterpreter( sal_uInt16 nError ) const;
void PutDouble(double fVal, SCSIZE nC, SCSIZE nR);
void PutDouble( double fVal, SCSIZE nIndex);
void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
void PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR);
void PutString(const ::rtl::OUString& rStr, SCSIZE nIndex);
void PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
void PutEmpty(SCSIZE nC, SCSIZE nR);
void PutEmptyPath(SCSIZE nC, SCSIZE nR);
......@@ -495,6 +499,16 @@ void ScMatrixImpl::PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
}
}
void ScMatrixImpl::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
{
if (ValidColRow( nC, nR))
maMat.set(nR, nC, pArray, pArray + nLen);
else
{
OSL_FAIL("ScMatrixImpl::PutDouble: dimension error");
}
}
void ScMatrixImpl::PutDouble( double fVal, SCSIZE nIndex)
{
SCSIZE nC, nR;
......@@ -505,7 +519,17 @@ void ScMatrixImpl::PutDouble( double fVal, SCSIZE nIndex)
void ScMatrixImpl::PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR)
{
if (ValidColRow( nC, nR))
maMat.set(nR, nC, rtl::OUString(rStr));
maMat.set(nR, nC, rStr);
else
{
OSL_FAIL("ScMatrixImpl::PutString: dimension error");
}
}
void ScMatrixImpl::PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
{
if (ValidColRow( nC, nR))
maMat.set(nR, nC, pArray, pArray + nLen);
else
{
OSL_FAIL("ScMatrixImpl::PutString: dimension error");
......@@ -1181,6 +1205,11 @@ void ScMatrix::PutDouble( double fVal, SCSIZE nIndex)
pImpl->PutDouble(fVal, nIndex);
}
void ScMatrix::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
{
pImpl->PutDouble(pArray, nLen, nC, nR);
}
void ScMatrix::PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR)
{
pImpl->PutString(rStr, nC, nR);
......@@ -1191,6 +1220,11 @@ void ScMatrix::PutString(const ::rtl::OUString& rStr, SCSIZE nIndex)
pImpl->PutString(rStr, nIndex);
}
void ScMatrix::PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
{
pImpl->PutString(pArray, nLen, nC, nR);
}
void ScMatrix::PutEmpty(SCSIZE nC, SCSIZE nR)
{
pImpl->PutEmpty(nC, nR);
......
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