sc/inc/column.hxx | 5 ++++- sc/source/core/data/column.cxx | 4 ++-- sc/source/core/data/table2.cxx | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-)
New commits: commit bc601af632861896bdfaa14c96daf1a7ffdfcf71 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Tue Mar 29 12:47:27 2022 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Tue Mar 29 14:25:14 2022 +0200 avoid repeated calls to ScMarkData::GetMarkedRanges() (tdf#148147) ScTable::HasSelectionMatrixFragment() gets called several times when opening 'Sheet' in the menubar, and the functions it calls end up a quadratic cost for the number of columns repeatedly calling ScMarkData::GetMarkedRanges() for the same object. Fix the performance problem by getting the value once and reusing it. Change-Id: I8b05475832c3560318c43429c3b9323035a3691f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132267 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index db72de87bbf1..372aef84c24e 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -299,7 +299,10 @@ public: SCSIZE VisibleCount( SCROW nStartRow, SCROW nEndRow ) const; sc::MatrixEdge GetBlockMatrixEdges(SCROW nRow1, SCROW nRow2, sc::MatrixEdge nMask, bool bNoMatrixAtAll ) const; - bool HasSelectionMatrixFragment(const ScMarkData& rMark) const; + // Repeated calls to HasSelectionMatrixFragment() repeatedly call rMark.GetMarkedRanges(), + // which may be quite slow. For that reason first save the result of rMark.GetMarkedRanges() + // pass that to HasSelectionMatrixFragment() calls. + bool HasSelectionMatrixFragment(const ScMarkData& rMark, const ScRangeList& rRangeList) const; bool GetFirstVisibleAttr( SCROW& rFirstRow ) const; bool GetLastVisibleAttr( SCROW& rLastRow ) const; diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index d75d9885fba6..19fb532ee74f 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -190,7 +190,7 @@ sc::MatrixEdge ScColumn::GetBlockMatrixEdges( SCROW nRow1, SCROW nRow2, sc::Matr return nEdges; } -bool ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark) const +bool ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark, const ScRangeList& rRangeList) const { using namespace sc; @@ -201,7 +201,7 @@ bool ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark) const ScAddress aCurOrigin = aOrigin; bool bOpen = false; - ScRangeList aRanges = rMark.GetMarkedRanges(); + ScRangeList aRanges = rRangeList; // cached rMark.GetMarkedRanges(), for performance reasons (tdf#148147) for (size_t i = 0, n = aRanges.size(); i < n; ++i) { const ScRange& r = aRanges[i]; diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 6ac918f34ef5..6c3aff760bf6 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2579,13 +2579,14 @@ bool ScTable::HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCO bool ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const { std::vector<sc::ColRowSpan> aSpans = rMark.GetMarkedColSpans(); + ScRangeList rangeList = rMark.GetMarkedRanges(); for (const sc::ColRowSpan & aSpan : aSpans) { SCCOL nEndCol = ClampToAllocatedColumns(aSpan.mnEnd); for ( SCCOLROW j=aSpan.mnStart; j<=nEndCol; j++ ) { - if ( aCol[j].HasSelectionMatrixFragment(rMark) ) + if ( aCol[j].HasSelectionMatrixFragment(rMark, rangeList) ) return true; } }