diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-06-26 13:49:20 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-06-26 14:41:18 +0200 |
commit | ea19b0c0230fcc730245ecd445c03164cb6a1d18 (patch) | |
tree | 33770c2daf8469ea161db560d6403bbd406ca8ef | |
parent | ad9ae59ecb2e33546617ef7afb3a019220e61853 (diff) |
tdf#113112 insert a new sheet slow
We were spending vast amounts of time in ScColumn::EndListening calling
set_empty on the mdds_vector, which moved the block data around.
So walk backwards through the data, which means we will delete from the
end, and largely avoid any expensive moving around.
Change-Id: I78cbecedf137972fb2a1b7042635f4e7b03d77ff
Reviewed-on: https://gerrit.libreoffice.org/74738
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | sc/inc/mtvcellfunc.hxx | 4 | ||||
-rw-r--r-- | sc/inc/mtvfunctions.hxx | 36 |
2 files changed, 37 insertions, 3 deletions
diff --git a/sc/inc/mtvcellfunc.hxx b/sc/inc/mtvcellfunc.hxx index 145d1ee38779..562d003a5c50 100644 --- a/sc/inc/mtvcellfunc.hxx +++ b/sc/inc/mtvcellfunc.hxx @@ -119,8 +119,10 @@ ParseFormulaNumeric( template<typename Func> void ProcessFormulaEditText(CellStoreType& rStore, Func& rFunc) { + // Walk backwards through the data - this helps when the FuncElem will be deleting + // stuff, so we don't continually move block data around. FuncElseNoOp<size_t> aElse; - ProcessElements2<CellStoreType, edittext_block, formula_block, Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse); + ProcessElements2Reverse<CellStoreType, edittext_block, formula_block, Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse); } template<typename Func> diff --git a/sc/inc/mtvfunctions.hxx b/sc/inc/mtvfunctions.hxx index f9052edfb27c..5e48bb2942d7 100644 --- a/sc/inc/mtvfunctions.hxx +++ b/sc/inc/mtvfunctions.hxx @@ -113,8 +113,18 @@ void EachElem(NodeT& rNode, size_t nOffset, size_t nDataSize, FuncElem& rFuncEle template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem> void EachElem(NodeT& rNode, FuncElem& rFuncElem) { - ItrT it = BlkT::begin(*rNode.data); - ItrT itEnd = BlkT::end(*rNode.data); + auto it = BlkT::begin(*rNode.data); + auto itEnd = BlkT::end(*rNode.data); + size_t nRow = rNode.position; + for (; it != itEnd; ++it, ++nRow) + rFuncElem(nRow, *it); +} + +template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem> +void EachElemReverse(NodeT& rNode, FuncElem& rFuncElem) +{ + auto it = BlkT::rbegin(*rNode.data); + auto itEnd = BlkT::rend(*rNode.data); size_t nRow = rNode.position; for (; it != itEnd; ++it, ++nRow) rFuncElem(nRow, *it); @@ -374,6 +384,28 @@ void ProcessElements2(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse) } } +template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse> +void ProcessElements2Reverse(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse) +{ + typename StoreT::size_type nTopRow = 0, nDataSize = 0; + typename StoreT::iterator it = rStore.begin(), itEnd = rStore.end(); + for (; it != itEnd; ++it, nTopRow += nDataSize) + { + nDataSize = it->size; + switch (it->type) + { + case Blk1::block_type: + EachElemReverse<Blk1, typename Blk1::iterator>(*it, rFuncElem); + break; + case Blk2::block_type: + EachElemReverse<Blk2, typename Blk2::iterator>(*it, rFuncElem); + break; + default: + rFuncElse(it->type, nTopRow, nDataSize); + } + } +} + template<typename StoreT, typename Blk1, typename FuncElem, typename FuncElse> std::pair<typename StoreT::const_iterator, typename StoreT::size_type> FindElement1( |