From ea19b0c0230fcc730245ecd445c03164cb6a1d18 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Wed, 26 Jun 2019 13:49:20 +0200 Subject: 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 --- sc/inc/mtvcellfunc.hxx | 4 +++- 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 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 aElse; - ProcessElements2 >(rStore, rFunc, aElse); + ProcessElements2Reverse >(rStore, rFunc, aElse); } template 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 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 +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 +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(*it, rFuncElem); + break; + case Blk2::block_type: + EachElemReverse(*it, rFuncElem); + break; + default: + rFuncElse(it->type, nTopRow, nDataSize); + } + } +} + template std::pair FindElement1( -- cgit