summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-11-11 15:34:46 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-11-11 15:38:55 -0500
commit2acfd789fbff24da0d92ce00e4d3d02097df4d9d (patch)
tree7978707286d85b25d161167a5a2f1a6612cfb1bd
parentsc:opencl waste less time measuring CPU performance. (diff)
downloadcore-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.cxx14
-rw-r--r--sc/source/core/inc/bcaslot.hxx9
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;
/**