summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2018-06-14 17:02:05 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2018-06-15 09:03:53 +0200
commit20083840700518d8c0ec314974249254eb859de7 (patch)
treec66414ca4e0345bfffbb5338d77941396310a462
parentd8142da066b6ee80444694e0eb6b0da9375a89c7 (diff)
tdf#94792 performance regression for xlsx with chart with >1000 data labels
this speeds things up by 30% for me Change-Id: I7fa99e91b0b4f354329803b9c8fab827bd367dac Reviewed-on: https://gerrit.libreoffice.org/55812 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r--svl/source/notify/SfxBroadcaster.cxx29
1 files changed, 24 insertions, 5 deletions
diff --git a/svl/source/notify/SfxBroadcaster.cxx b/svl/source/notify/SfxBroadcaster.cxx
index f4e00e860333..2e312a80ce85 100644
--- a/svl/source/notify/SfxBroadcaster.cxx
+++ b/svl/source/notify/SfxBroadcaster.cxx
@@ -124,13 +124,32 @@ void SfxBroadcaster::Forward(SfxBroadcaster& rBC, const SfxHint& rHint)
void SfxBroadcaster::RemoveListener( SfxListener& rListener )
{
DBG_TESTSOLARMUTEX();
- SfxListenerArr_Impl::iterator aIter = std::find(
- mpImpl->m_Listeners.begin(), mpImpl->m_Listeners.end(), &rListener);
- assert(aIter != mpImpl->m_Listeners.end()); // "RemoveListener: Listener unknown"
+
+ // First, check the slots either side of the last removed slot, makes a significant
+ // difference when the list is large.
+ int positionOfRemovedElement = -1;
+ if (!mpImpl->m_RemovedPositions.empty())
+ {
+ auto i = mpImpl->m_RemovedPositions.back();
+ if (i < mpImpl->m_Listeners.size() - 2 && mpImpl->m_Listeners[i+1] == &rListener)
+ {
+ positionOfRemovedElement = i + 1;
+ }
+ else if (i > 0 && mpImpl->m_Listeners[i-1] == &rListener)
+ {
+ positionOfRemovedElement = i-1;
+ }
+ }
+ // then scan the whole list if we didn't find it
+ if (positionOfRemovedElement == -1)
+ {
+ SfxListenerArr_Impl::iterator aIter = std::find(
+ mpImpl->m_Listeners.begin(), mpImpl->m_Listeners.end(), &rListener);
+ positionOfRemovedElement = std::distance(mpImpl->m_Listeners.begin(), aIter);
+ }
// DO NOT erase the listener, set the pointer to 0
// because the current continuation may contain this->Broadcast
- *aIter = nullptr;
- size_t positionOfRemovedElement = std::distance(mpImpl->m_Listeners.begin(), aIter);
+ mpImpl->m_Listeners[positionOfRemovedElement] = nullptr;
mpImpl->m_RemovedPositions.push_back(positionOfRemovedElement);
}