summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-06-26 13:49:20 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-06-26 14:41:18 +0200
commitea19b0c0230fcc730245ecd445c03164cb6a1d18 (patch)
tree33770c2daf8469ea161db560d6403bbd406ca8ef
parentad9ae59ecb2e33546617ef7afb3a019220e61853 (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.hxx4
-rw-r--r--sc/inc/mtvfunctions.hxx36
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(