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;
         }
     }

Reply via email to