diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-11-11 15:34:46 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-11-11 15:38:55 -0500 |
commit | 2acfd789fbff24da0d92ce00e4d3d02097df4d9d (patch) | |
tree | 7978707286d85b25d161167a5a2f1a6612cfb1bd | |
parent | sc:opencl waste less time measuring CPU performance. (diff) | |
download | core-2acfd789fbff24da0d92ce00e4d3d02097df4d9d.tar.gz core-2acfd789fbff24da0d92ce00e4d3d02097df4d9d.zip |
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
-rw-r--r-- | sc/source/core/data/bcaslot.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/inc/bcaslot.hxx | 9 |
2 files changed, 21 insertions, 2 deletions
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx index ad340a18b82d..f2609a4aea9d 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 59812af0d114..830ddeaa216d 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; /** |