sc/inc/column.hxx                     |    2 ++
 sc/source/core/data/column2.cxx       |   23 +++++++++++++++++++++++
 sc/source/core/tool/sharedformula.cxx |   13 ++++---------
 3 files changed, 29 insertions(+), 9 deletions(-)

New commits:
commit e63e494d56c83c93db819532cd17574844366f02
Author:     Noel Grandin <[email protected]>
AuthorDate: Wed Oct 1 11:25:45 2025 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Fri Oct 3 13:34:41 2025 +0200

    tdf#133557 Rejecting track & changes in Calc slow
    
    create a specialised path for this, which avoids some of
    the overhead, reduces the time spent by half for me.
    
    Still confused why we are not using the BASM machinery here,
    seems like we could be a lot faster.
    
    Change-Id: Ifa0e704deb358816cf47a9e3e79309e0c1e8c45a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191712
    Reviewed-by: Noel Grandin <[email protected]>
    Tested-by: Jenkins

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 0c6be7ea0c6d..b11b6cf3917e 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -612,6 +612,8 @@ public:
     void        EndListening( SvtListener& rLst, SCROW nRow );
     void StartListening( sc::StartListeningContext& rCxt, const ScAddress& 
rAddress, SvtListener& rListener );
     void EndListening( sc::EndListeningContext& rCxt, const ScAddress& 
rAddress, SvtListener& rListener );
+    void StartListeningSingleRefFormulaCells( sc::StartListeningContext& rCxt, 
const ScSingleRefData* pRef,
+                                const ScAddress& rAddress, ScFormulaCell** pp, 
ScFormulaCell** ppEnd );
     void StartListeners( sc::StartListeningContext& rCxt, bool bAll );
     void        SetDirtyIfPostponed();
     void BroadcastRecalcOnRefMove();
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index dc09a0066669..4347c524efa6 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -3551,6 +3551,29 @@ void ScColumn::EndListening( sc::EndListeningContext& 
rCxt, const ScAddress& rAd
         rCxt.addEmptyBroadcasterPosition(rAddress.Tab(), rAddress.Col(), 
rAddress.Row());
 }
 
+void ScColumn::StartListeningSingleRefFormulaCells( sc::StartListeningContext& 
rCxt,
+                    const ScSingleRefData* pRef,
+                    const ScAddress& rAddress, ScFormulaCell** pp, 
ScFormulaCell** ppEnd )
+{
+    sc::ColumnBlockPosition* p = rCxt.getBlockPosition(rAddress.Tab(), 
rAddress.Col());
+    if (!p)
+        return;
+    sc::BroadcasterStoreType::iterator& it = p->miBroadcasterPos;
+    ScAddress aPos(rAddress);
+    for (; pp != ppEnd; ++pp)
+    {
+        if (!aPos.IsValid())
+            break;
+
+        std::pair<sc::BroadcasterStoreType::iterator,size_t> aBroadcasterPos = 
maBroadcasters.position(it, aPos.Row());
+        it = aBroadcasterPos.first; // store the block position for next 
iteration.
+        startListening(maBroadcasters, it, aBroadcasterPos.second, aPos.Row(), 
**pp);
+
+        if (pRef->IsRowRel())
+            aPos.IncRow();
+    }
+}
+
 namespace {
 
 class CompileDBFormulaHandler
diff --git a/sc/source/core/tool/sharedformula.cxx 
b/sc/source/core/tool/sharedformula.cxx
index 98fa783c07ae..499264900861 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -14,6 +14,7 @@
 #include <document.hxx>
 #include <grouparealistener.hxx>
 #include <refdata.hxx>
+#include <table.hxx>
 
 namespace sc {
 
@@ -382,15 +383,9 @@ void SharedFormulaUtil::startListeningAsGroup( 
sc::StartListeningContext& rCxt,
                 ScAddress aPos = pRef->toAbs(rDoc, rTopCell.aPos);
                 ScFormulaCell** pp = ppSharedTop;
                 ScFormulaCell** ppEnd = ppSharedTop + xGroup->mnLength;
-                for (; pp != ppEnd; ++pp)
-                {
-                    if (!aPos.IsValid())
-                        break;
-
-                    rDoc.StartListeningCell(rCxt, aPos, **pp);
-                    if (pRef->IsRowRel())
-                        aPos.IncRow();
-                }
+                if (aPos.IsValid())
+                    if (ScTable* pTable = rDoc.FetchTable(aPos.Tab()))
+                        
pTable->CreateColumnIfNotExists(aPos.Col()).StartListeningSingleRefFormulaCells(rCxt,
 pRef, aPos, pp, ppEnd);
             }
             break;
             case formula::svDoubleRef:

Reply via email to