summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2018-12-07 17:37:15 +0100
committerEike Rathke <erack@redhat.com>2018-12-14 16:25:03 +0100
commita3fb726f4972c5a869e778353c8c1c19f149c5ea (patch)
tree9b4859024517176c6c1798b55c090ee8dafc944b
parent77ca13a212a570f7b8c369f468b6dfa08d4ab6e0 (diff)
optimize expensive EndListener() calls (tdf#102364)
The document has a large (1M cells) column, and when replacing old cells with new cells during undo as described in the bugreport the repeated calls to EndListener() from ScColumn::DetachFormulaCell() get quite costly. Optimize this by doing a single EndListeningFormulaCells() call. Change-Id: If51dacdfbe876134de956dbc6bbd73e97d9686ff Reviewed-on: https://gerrit.libreoffice.org/64781 Tested-by: Jenkins Reviewed-by: Kohei Yoshida <libreoffice@kohei.us> Reviewed-by: Eike Rathke <erack@redhat.com>
-rw-r--r--sc/source/core/data/column.cxx9
1 files changed, 9 insertions, 0 deletions
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index bfd11e038bf0..0c151a70ac65 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1633,6 +1633,15 @@ public:
sc::formula_block::const_iterator itEnd = it;
std::advance(itEnd, nDataSize);
+ if(nDataSize > 1024 && (mnCopyFlags & InsertDeleteFlags::FORMULA) != InsertDeleteFlags::NONE)
+ {
+ // If the column to be replaced contains a long formula group (tdf#102364), there can
+ // be so many listeners in a single vector that the quadratic cost of repeatedly removing
+ // the first element becomes very high. Optimize this by removing them in one go.
+ sc::EndListeningContext context(*mrDestCol.GetDoc());
+ mrDestCol.EndListeningFormulaCells( context, nRow, nRow + nDataSize - 1, nullptr, nullptr );
+ }
+
for (; it != itEnd; ++it, ++nRow)
cloneFormulaCell(nRow, **it);
}