From b7d3e9ce25643bfb5af3e9e8ab3b80bb021b10ea Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Fri, 3 May 2024 20:49:31 +0200 Subject: [PATCH] speedup configmgr::Access on Windows std::multiset seems to be pretty slow to construct and destruct, even if we ~never put anything into these listener lists, so rather use o3tl::sorted_vector, which has more predictable performance. Shaves 10% off startup time for me. Change-Id: I13afcbe3cb63522e4efe61c64f773e1ffbec9683 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167101 Tested-by: Jenkins Reviewed-by: Noel Grandin --- configmgr/source/access.cxx | 28 +++++++++++++++++----------- configmgr/source/access.hxx | 11 ++++++----- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx index 44a47e74b331..b8d174b4b086 100644 --- a/configmgr/source/access.cxx +++ b/configmgr/source/access.cxx @@ -326,7 +326,7 @@ void Access::removeEventListener( assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - DisposeListeners::iterator i(disposeListeners_.find(aListener)); + auto i(disposeListeners_.find(aListener)); if (i != disposeListeners_.end()) { disposeListeners_.erase(i); } @@ -580,7 +580,7 @@ void Access::removeContainerListener( assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - ContainerListeners::iterator i(containerListeners_.find(xListener)); + auto i(containerListeners_.find(xListener)); if (i != containerListeners_.end()) { containerListeners_.erase(i); } @@ -823,7 +823,7 @@ void Access::removePropertyChangeListener( PropertyChangeListeners::iterator i( propertyChangeListeners_.find(aPropertyName)); if (i != propertyChangeListeners_.end()) { - PropertyChangeListenersElement::iterator j(i->second.find(aListener)); + auto j(i->second.find(aListener)); if (j != i->second.end()) { i->second.erase(j); if (i->second.empty()) { @@ -869,7 +869,7 @@ void Access::removeVetoableChangeListener( VetoableChangeListeners::iterator i( vetoableChangeListeners_.find(PropertyName)); if (i != vetoableChangeListeners_.end()) { - VetoableChangeListenersElement::iterator j(i->second.find(aListener)); + auto j(i->second.find(aListener)); if (j != i->second.end()) { i->second.erase(j); if (i->second.empty()) { @@ -958,8 +958,7 @@ void Access::removePropertiesChangeListener( { assert(thisIs(IS_GROUP)); osl::MutexGuard g(*lock_); - PropertiesChangeListeners::iterator i( - propertiesChangeListeners_.find(xListener)); + auto i(propertiesChangeListeners_.find(xListener)); if (i != propertiesChangeListeners_.end()) { propertiesChangeListeners_.erase(i); } @@ -1285,13 +1284,17 @@ Access::~Access() {} void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { assert(broadcaster != nullptr); - for (auto const& disposeListener : disposeListeners_) + // make copies when we fire listeners, since the vectors can + // be modified by the callees. + auto disposeCopy = disposeListeners_; + for (auto const& disposeListener : disposeCopy) { broadcaster->addDisposeNotification( disposeListener, css::lang::EventObject(getXWeak())); } - for (auto const& containerListener : containerListeners_) + auto containerCopy = containerListeners_; + for (auto const& containerListener : containerCopy) { broadcaster->addDisposeNotification( containerListener, @@ -1299,7 +1302,8 @@ void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { } for (auto const& propertyChangeListener : propertyChangeListeners_) { - for (auto const& propertyChangeListenerElement : propertyChangeListener.second) + auto propChangeCopy = propertyChangeListener.second; + for (auto const& propertyChangeListenerElement : propChangeCopy) { broadcaster->addDisposeNotification( propertyChangeListenerElement, @@ -1309,7 +1313,8 @@ void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { } for (auto const& vetoableChangeListener : vetoableChangeListeners_) { - for (auto const& vetoableChangeListenerElement : vetoableChangeListener.second) + auto vetoCopy = vetoableChangeListener.second; + for (auto const& vetoableChangeListenerElement : vetoCopy) { broadcaster->addDisposeNotification( vetoableChangeListenerElement, @@ -1317,7 +1322,8 @@ void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { getXWeak())); } } - for (auto const& propertiesChangeListener : propertiesChangeListeners_) + auto propCopy = propertiesChangeListeners_; + for (auto const& propertiesChangeListener : propCopy) { broadcaster->addDisposeNotification( propertiesChangeListener, diff --git a/configmgr/source/access.hxx b/configmgr/source/access.hxx index bd93b4222177..6a30875591f8 100644 --- a/configmgr/source/access.hxx +++ b/configmgr/source/access.hxx @@ -23,6 +23,7 @@ #include #include +#include #include "config_map.hxx" #include @@ -402,19 +403,19 @@ private: typedef config_map< ChildAccess * > WeakChildMap; typedef - std::multiset< + o3tl::sorted_vector< css::uno::Reference< css::lang::XEventListener > > DisposeListeners; typedef - std::multiset< + o3tl::sorted_vector< css::uno::Reference< css::container::XContainerListener > > ContainerListeners; typedef - std::multiset< + o3tl::sorted_vector< css::uno::Reference< css::beans::XPropertyChangeListener > > PropertyChangeListenersElement; @@ -423,7 +424,7 @@ private: PropertyChangeListeners; typedef - std::multiset< + o3tl::sorted_vector< css::uno::Reference< css::beans::XVetoableChangeListener > > VetoableChangeListenersElement; @@ -432,7 +433,7 @@ private: VetoableChangeListeners; typedef - std::multiset< + o3tl::sorted_vector< css::uno::Reference< css::beans::XPropertiesChangeListener > > PropertiesChangeListeners;