[Libreoffice-commits] core.git: Branch 'feature/perfwork5' - sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Tue Nov 11 12:40:38 PST 2014


 sc/source/core/data/bcaslot.cxx |   14 ++++++++++++--
 sc/source/core/inc/bcaslot.hxx  |    9 +++++++++
 2 files changed, 21 insertions(+), 2 deletions(-)

New commits:
commit 2acfd789fbff24da0d92ce00e4d3d02097df4d9d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Nov 11 15:34:46 2014 -0500

    Optimize area broadcast iteration ...
    
    for cases where no areas are marked for removal, which I believe is mor
    common use case than others.
    
    Change-Id: I3f53fb5e6ab4a9172e358bec0c71289d1e92ac19

diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index ad340a1..f2609a4 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -108,7 +108,8 @@ ScBroadcastAreaSlot::ScBroadcastAreaSlot( ScDocument* pDocument,
     aTmpSeekBroadcastArea( ScRange()),
     pDoc( pDocument ),
     pBASM( pBASMa ),
-    mbInBroadcastIteration( false)
+    mbInBroadcastIteration( false),
+    mbHasErasedArea(false)
 {
 }
 
@@ -247,15 +248,20 @@ bool ScBroadcastAreaSlot::AreaBroadcast( const ScHint& rHint)
 {
     if (aBroadcastAreaTbl.empty())
         return false;
+
     bool bInBroadcast = mbInBroadcastIteration;
     mbInBroadcastIteration = true;
     bool bIsBroadcasted = false;
+
+    mbHasErasedArea = false;
+
     const ScAddress& rAddress = rHint.GetAddress();
     for (ScBroadcastAreas::const_iterator aIter( aBroadcastAreaTbl.begin()),
             aIterEnd( aBroadcastAreaTbl.end()); aIter != aIterEnd; ++aIter )
     {
-        if (isMarkedErased( aIter))
+        if (mbHasErasedArea && isMarkedErased( aIter))
             continue;
+
         ScBroadcastArea* pArea = (*aIter).mpArea;
         const ScRange& rAreaRange = pArea->GetRange();
         if (rAreaRange.In( rAddress))
@@ -267,11 +273,14 @@ bool ScBroadcastAreaSlot::AreaBroadcast( const ScHint& rHint)
             }
         }
     }
+
     mbInBroadcastIteration = bInBroadcast;
+
     // A Notify() during broadcast may call EndListeningArea() and thus dispose
     // an area if it was the last listener, which would invalidate an iterator
     // pointing to it, hence the real erase is done afterwards.
     FinallyEraseAreas();
+
     return bIsBroadcasted;
 }
 
@@ -418,6 +427,7 @@ void ScBroadcastAreaSlot::EraseArea( ScBroadcastAreas::iterator& rIter )
     if (mbInBroadcastIteration)
     {
         (*rIter).mbErasure = true;      // mark for erasure
+        mbHasErasedArea = true; // at least one area is marked for erasure.
         pBASM->PushAreaToBeErased( this, rIter);
     }
     else
diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx
index 59812af..830ddea 100644
--- a/sc/source/core/inc/bcaslot.hxx
+++ b/sc/source/core/inc/bcaslot.hxx
@@ -136,6 +136,15 @@ private:
     ScBroadcastAreaSlotMachine* pBASM;
     bool                mbInBroadcastIteration;
 
+    /**
+     * If true, the slot has at least one area broadcaster marked for removal.
+     * This flag is used only during broadcast iteration, to speed up
+     * iteration.  Using this flag is cheaper than dereferencing each iterator
+     * and checking its own flag inside especially when no areas are marked
+     * for removal.
+     */
+    bool mbHasErasedArea;
+
     ScBroadcastAreas::const_iterator  FindBroadcastArea( const ScRange& rRange ) const;
 
     /**


More information about the Libreoffice-commits mailing list