sc/inc/scmatrix.hxx | 12 ++ sc/source/core/tool/scmatrix.cxx | 130 +++++++++++++++++++++++++++++++ sc/source/ui/docshell/externalrefmgr.cxx | 42 +++------- 3 files changed, 156 insertions(+), 28 deletions(-)
New commits: commit f18cb2c196cc5b643b9832dfca1d940b82c832b0 Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Tue Feb 16 07:07:53 2016 +0100 single element access is really slow in mdds, tdf#67071 Change-Id: I5491ba0bc44a9ce8844b31126835671c5d5abcaa Reviewed-on: https://gerrit.libreoffice.org/22386 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Markus Mohrhard <markus.mohrh...@googlemail.com> diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 9287f55..84eda9e 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -123,6 +123,10 @@ protected: public: enum Op { Add, Sub, Mul, Div }; + typedef std::function<void(size_t, size_t, double)> DoubleOpFunction; + typedef std::function<void(size_t, size_t, bool)> BoolOpFunction; + typedef std::function<void(size_t, size_t, svl::SharedString)> StringOpFunction; + /** * When adding all numerical matrix elements for a scalar result such as * summation, the interpreter wants to separate the first non-zero value @@ -393,6 +397,9 @@ public: virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) = 0; + virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos, + DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const = 0; + #if DEBUG_MATRIX void Dump() const; #endif @@ -598,6 +605,8 @@ public: virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) override; + virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos, + DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const; ScFullMatrix& operator+= ( const ScFullMatrix& r ); #if DEBUG_MATRIX @@ -806,6 +815,9 @@ public: virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) override; + virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos, + DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const; + ScVectorRefMatrix& operator+=(const ScVectorRefMatrix& r); }; diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 33879bc..6019cc2 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -300,6 +300,10 @@ public: template<typename T> void ApplyOperation(T aOp, ScMatrixImpl& rMat); + void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, + const std::pair<size_t, size_t>& rEndPos, ScFullMatrix::DoubleOpFunction aDoubleFunc, + ScFullMatrix::BoolOpFunction aBoolFunc, ScFullMatrix::StringOpFunction aStringFunc) const; + template<typename T> std::vector<ScMatrix::IterateResult> ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp); @@ -2169,6 +2173,117 @@ std::vector<ScMatrix::IterateResult> ScMatrixImpl::ApplyCollectOperation(bool bT return aFunc.getResult(); } +namespace { + +class WalkElementBlockOperation +{ +public: + + WalkElementBlockOperation(size_t nRowSize, size_t /*nColSize*/, + ScFullMatrix::DoubleOpFunction aDoubleFunc, + ScFullMatrix::BoolOpFunction aBoolFunc, + ScFullMatrix::StringOpFunction aStringFunc): + mnRowSize(nRowSize), + mnRowPos(0), + mnColPos(0), + maDoubleFunc(aDoubleFunc), + maBoolFunc(aBoolFunc), + maStringFunc(aStringFunc) + { + } + + void operator()(const MatrixImplType::element_block_node_type& node) + { + switch (node.type) + { + case mdds::mtm::element_numeric: + { + typedef MatrixImplType::numeric_block_type block_type; + + block_type::const_iterator it = block_type::begin(*node.data); + std::advance(it, node.offset); + block_type::const_iterator itEnd = it; + std::advance(itEnd, node.size); + for (auto itr = it; itr != itEnd; ++itr) + { + maDoubleFunc(mnRowPos, mnColPos, *itr); + ++mnRowPos; + if (mnRowPos >= mnRowSize) + { + mnRowPos = 0; + ++mnColPos; + } + } + } + break; + case mdds::mtm::element_string: + { + typedef MatrixImplType::string_block_type block_type; + + block_type::const_iterator it = block_type::begin(*node.data); + std::advance(it, node.offset); + block_type::const_iterator itEnd = it; + std::advance(itEnd, node.size); + for (auto itr = it; itr != itEnd; ++itr) + { + maStringFunc(mnRowPos, mnColPos, *itr); + ++mnRowPos; + if (mnRowPos >= mnRowSize) + { + mnRowPos = 0; + ++mnColPos; + } + } + } + break; + case mdds::mtm::element_boolean: + { + typedef MatrixImplType::boolean_block_type block_type; + + block_type::const_iterator it = block_type::begin(*node.data); + std::advance(it, node.offset); + block_type::const_iterator itEnd = it; + std::advance(itEnd, node.size); + for (auto itr = it; itr != itEnd; ++itr) + { + maBoolFunc(mnRowPos, mnColPos, *itr); + ++mnRowPos; + if (mnRowPos >= mnRowSize) + { + mnRowPos = 0; + ++mnColPos; + } + } + } + break; + case mdds::mtm::element_empty: + break; + } + } + +private: + + size_t mnRowSize; + size_t mnRowPos; + size_t mnColPos; + + ScFullMatrix::DoubleOpFunction maDoubleFunc; + ScFullMatrix::BoolOpFunction maBoolFunc; + ScFullMatrix::StringOpFunction maStringFunc; +}; + +} + +void ScMatrixImpl::ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, + const std::pair<size_t, size_t>& rEndPos, ScMatrix::DoubleOpFunction aDoubleFunc, + ScMatrix::BoolOpFunction aBoolFunc, ScMatrix::StringOpFunction aStringFunc) const +{ + WalkElementBlockOperation aFunc(maMat.size().row, maMat.size().column, + aDoubleFunc, aBoolFunc, aStringFunc); + maMat.walk(aFunc, MatrixImplType::size_pair_type(rStartPos.first, rStartPos.second), + MatrixImplType::size_pair_type(rEndPos.first, rEndPos.second)); +} + #if DEBUG_MATRIX void ScMatrixImpl::Dump() const @@ -2817,6 +2932,13 @@ void ScFullMatrix::PowOp( bool bFlag, double fVal, ScMatrix& rMat) } } +void ScFullMatrix::ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, + const std::pair<size_t, size_t>& rEndPos, DoubleOpFunction aDoubleFunc, + BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const +{ + pImpl->ExecuteOperation(rStartPos, rEndPos, aDoubleFunc, aBoolFunc, aStringFunc); +} + std::vector<ScMatrix::IterateResult> ScFullMatrix::Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) { return pImpl->ApplyCollectOperation(bTextAsZero, aOp); @@ -3555,4 +3677,12 @@ std::vector<ScMatrix::IterateResult> ScVectorRefMatrix::Collect(bool bTextAsZero return mpFullMatrix->Collect(bTextAsZero, aOp); } +void ScVectorRefMatrix::ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, + const std::pair<size_t, size_t>& rEndPos, DoubleOpFunction aDoubleFunc, + BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const +{ + const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix(); + mpFullMatrix->ExecuteOperation(rStartPos, rEndPos, aDoubleFunc, aBoolFunc, aStringFunc); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index 699ac27..7bbf7b7 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -791,35 +791,21 @@ void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRa pTabData.reset(new Table); const ScMatrixRef& pMat = itrData->mpRangeData; - for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow) + ScFullMatrix::DoubleOpFunction aDoubleFunc = [=](size_t row, size_t col, double val) -> void { - const SCSIZE nR = nRow - nRow1; - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) - { - const SCSIZE nC = nCol - nCol1; - - ScMatrixValue value = pMat->Get(nC, nR); - - TokenRef pToken; - - switch (value.nType) { - case SC_MATVAL_VALUE: - case SC_MATVAL_BOOLEAN: - pToken.reset(new formula::FormulaDoubleToken(value.fVal)); - break; - case SC_MATVAL_STRING: - pToken.reset(new formula::FormulaStringToken(value.aStr)); - break; - default: - // Don't cache empty cells. - break; - } - - if (pToken) - // Don't mark this cell 'cached' here, for better performance. - pTabData->setCell(nCol, nRow, pToken, 0, false); - } - } + pTabData->setCell(col + nCol1, row + nRow1, new formula::FormulaDoubleToken(val), 0, false); + }; + ScFullMatrix::BoolOpFunction aBoolFunc = [=](size_t row, size_t col, bool val) -> void + { + pTabData->setCell(col + nCol1, row + nRow1, new formula::FormulaDoubleToken(val), 0, false); + }; + ScFullMatrix::StringOpFunction aStringFunc = [=](size_t row, size_t col, svl::SharedString val) -> void + { + pTabData->setCell(col + nCol1, row + nRow1, new formula::FormulaStringToken(val), 0, false); + }; + pMat->ExecuteOperation(std::pair<size_t, size_t>(0, 0), + std::pair<size_t, size_t>(nRow2-nRow1, nCol2-nCol1), + aDoubleFunc, aBoolFunc, aStringFunc); // Mark the whole range 'cached'. pTabData->setCachedCellRange(nCol1, nRow1, nCol2, nRow2); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits