From 38ae35db26cd5bed2eabc90e1a02afeb4e0eff54 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Sun, 10 Jul 2016 20:02:50 +0200 Subject: tdf#84635 - Slow layout of large tables Based on suggestion from Aron Budea. And do something similar to most other places keeping vectors of weak references where the code looks like it will hold more than a few entries. Measurements: the 26 page file file takes 51s without my path 15s with this patch the 69 page file file takes 5m28 without my path 51s with this patch the 84 page file file takes 8m28 without my path 58s with this patch Change-Id: I8da94c525fc73ebd969e0343c6f074be4f0063b1 Reviewed-on: https://gerrit.libreoffice.org/27093 Tested-by: Jenkins Reviewed-by: Noel Grandin --- .../source/standard/vclxaccessiblelist.cxx | 12 ++++++++---- basic/source/classes/sbunoobj.cxx | 8 ++------ dbaccess/source/core/dataaccess/ModelImpl.cxx | 13 +++++++++---- svl/source/filepicker/pickerhistory.cxx | 22 ++++------------------ sw/inc/doc.hxx | 12 ++++++------ sw/source/core/doc/doccorr.cxx | 2 ++ sw/source/core/doc/docnew.cxx | 1 + sw/source/uibase/misc/glosdoc.cxx | 10 +++++++--- unotools/source/config/cmdoptions.cxx | 9 ++++++--- unotools/source/config/eventcfg.cxx | 9 ++++++--- 10 files changed, 51 insertions(+), 47 deletions(-) diff --git a/accessibility/source/standard/vclxaccessiblelist.cxx b/accessibility/source/standard/vclxaccessiblelist.cxx index 66e1fa2d5134..b439dd122fb6 100644 --- a/accessibility/source/standard/vclxaccessiblelist.cxx +++ b/accessibility/source/standard/vclxaccessiblelist.cxx @@ -165,19 +165,23 @@ void VCLXAccessibleList::notifyVisibleStates(bool _bSetNew ) NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); ListItems::iterator aIter = m_aAccessibleChildren.begin(); - ListItems::iterator aEnd = m_aAccessibleChildren.end(); UpdateVisibleLineCount(); // adjust the index inside the VCLXAccessibleListItem - for (;aIter != aEnd ; ++aIter) + for ( ; aIter != m_aAccessibleChildren.end(); ) { Reference< XAccessible > xHold = *aIter; - VCLXAccessibleListItem* pItem = static_cast(xHold.get()); - if ( pItem ) + if (!xHold.is()) { + aIter = m_aAccessibleChildren.erase(aIter); + } + else + { + VCLXAccessibleListItem* pItem = static_cast(xHold.get()); const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0; const sal_Int32 nPos = static_cast(aIter - m_aAccessibleChildren.begin()); bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) ); pItem->SetVisible( m_bVisible && bVisible ); + ++aIter; } } diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx index 370ae2018a4e..21be5c9dee43 100644 --- a/basic/source/classes/sbunoobj.cxx +++ b/basic/source/classes/sbunoobj.cxx @@ -4576,13 +4576,9 @@ void disposeComVariablesForBasic( StarBASIC* pBasic ) ComponentRefVector::iterator itCRV; for( itCRV = rv.begin() ; itCRV != rv.end() ; ++itCRV ) { - try - { - Reference< XComponent > xComponent( (*itCRV).get(), UNO_QUERY_THROW ); + Reference< XComponent > xComponent( (*itCRV).get(), UNO_QUERY ); + if (xComponent.is()) xComponent->dispose(); - } - catch(const Exception& ) - {} } delete pItem; diff --git a/dbaccess/source/core/dataaccess/ModelImpl.cxx b/dbaccess/source/core/dataaccess/ModelImpl.cxx index 457777652298..d40a8f5c48a6 100644 --- a/dbaccess/source/core/dataaccess/ModelImpl.cxx +++ b/dbaccess/source/core/dataaccess/ModelImpl.cxx @@ -626,15 +626,20 @@ void SAL_CALL ODatabaseModelImpl::disposing( const css::lang::EventObject& Sourc if ( xCon.is() ) { bool bStore = false; - OWeakConnectionArray::const_iterator aEnd = m_aConnections.end(); - for (OWeakConnectionArray::iterator i = m_aConnections.begin(); aEnd != i; ++i) + for (OWeakConnectionArray::iterator i = m_aConnections.begin(); i != m_aConnections.end(); ) { - if ( xCon == i->get() ) + css::uno::Reference< css::sdbc::XConnection > xIterConn ( *i ); + if ( !xIterConn.is()) + { + i = m_aConnections.erase(i); + } + else if ( xCon == xIterConn ) { *i = css::uno::WeakReference< css::sdbc::XConnection >(); bStore = true; break; - } + } else + ++i; } if ( bStore ) diff --git a/svl/source/filepicker/pickerhistory.cxx b/svl/source/filepicker/pickerhistory.cxx index 29cc03b8e4eb..c4c4b03008e9 100644 --- a/svl/source/filepicker/pickerhistory.cxx +++ b/svl/source/filepicker/pickerhistory.cxx @@ -50,24 +50,10 @@ namespace svt return; // first, check which of the objects we hold in s_aHistory can be removed - { - InterfaceArray aCleanedHistory; - for ( InterfaceArray::const_iterator aLoop = _rHistory.begin(); - aLoop != _rHistory.end(); - ++aLoop - ) - { - Reference< XInterface > xCurrent( aLoop->get() ); - if ( xCurrent.is() ) - { - if ( aCleanedHistory.empty() ) - // make some room, assume that all interfaces (from here on) are valid - aCleanedHistory.reserve( _rHistory.size() - ( aLoop - _rHistory.begin() ) ); - aCleanedHistory.push_back( css::uno::WeakReference< XInterface >( xCurrent ) ); - } - } - _rHistory.swap( aCleanedHistory ); - } + _rHistory.erase(std::remove_if(_rHistory.begin(), + _rHistory.end(), + [](const css::uno::WeakReference< XInterface > & x) { return !x.get().is(); }), + _rHistory.end()); // then push_back the picker _rHistory.push_back( css::uno::WeakReference< XInterface >( _rxPicker ) ); diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index edf54f94f003..cfaefece1ed1 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1644,14 +1644,14 @@ public: std::vector< std::weak_ptr > mvUnoCursorTable; // Remove expired UnoCursor weak pointers the document keeps to notify about document death. - void cleanupUnoCursorTable() + void cleanupUnoCursorTable() const { + auto & rTable = const_cast(this)->mvUnoCursorTable; // In most cases we'll remove most of the elements. - std::vector< std::weak_ptr > unoCursorTable; - std::copy_if(mvUnoCursorTable.begin(), mvUnoCursorTable.end(), - std::back_inserter(unoCursorTable), - [](const std::weak_ptr& pWeakPtr) { return !pWeakPtr.expired(); }); - std::swap(mvUnoCursorTable, unoCursorTable); + rTable.erase( std::remove_if(rTable.begin(), + rTable.end(), + [] (std::weak_ptr const & x) { return x.expired(); }), + rTable.end()); } private: diff --git a/sw/source/core/doc/doccorr.cxx b/sw/source/core/doc/doccorr.cxx index e043c9137f6e..e207e856117d 100644 --- a/sw/source/core/doc/doccorr.cxx +++ b/sw/source/core/doc/doccorr.cxx @@ -121,6 +121,7 @@ void PaMCorrAbs( const SwPaM& rRange, } } + pDoc->cleanupUnoCursorTable(); for(const auto& pWeakUnoCursor : pDoc->mvUnoCursorTable) { auto pUnoCursor(pWeakUnoCursor.lock()); @@ -273,6 +274,7 @@ void PaMCorrRel( const SwNodeIndex &rOldNode, } } + pDoc->cleanupUnoCursorTable(); for(const auto& pWeakUnoCursor : pDoc->mvUnoCursorTable) { auto pUnoCursor(pWeakUnoCursor.lock()); diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx index 0e34dd0679ce..80c148ba2539 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -425,6 +425,7 @@ SwDoc::~SwDoc() getIDocumentRedlineAccess().GetExtraRedlineTable().DeleteAndDestroyAll(); const sw::DocDisposingHint aHint; + cleanupUnoCursorTable(); for(const auto& pWeakCursor : mvUnoCursorTable) { auto pCursor(pWeakCursor.lock()); diff --git a/sw/source/uibase/misc/glosdoc.cxx b/sw/source/uibase/misc/glosdoc.cxx index 0e054e5b125a..720bfcfdc8a1 100644 --- a/sw/source/uibase/misc/glosdoc.cxx +++ b/sw/source/uibase/misc/glosdoc.cxx @@ -442,18 +442,22 @@ void SwGlossaries::RemoveFileFromList( const OUString& rGroup ) // tell the UNO AutoTextGroup object that it's not valid anymore for ( UnoAutoTextGroups::iterator aLoop = m_aGlossaryGroups.begin(); aLoop != m_aGlossaryGroups.end(); - ++aLoop ) { Reference< container::XNamed > xNamed( aLoop->get(), UNO_QUERY ); - if ( xNamed.is() && ( xNamed->getName() == rGroup ) ) + if ( !xNamed.is() ) + { + aLoop = m_aGlossaryGroups.erase(aLoop); + } + else if ( xNamed->getName() == rGroup ) { static_cast< SwXAutoTextGroup* >( xNamed.get() )->Invalidate(); // note that this static_cast works because we know that the array only // contains SwXAutoTextGroup implementation m_aGlossaryGroups.erase( aLoop ); break; - } + } else + ++aLoop; } } diff --git a/unotools/source/config/cmdoptions.cxx b/unotools/source/config/cmdoptions.cxx index c79ba2ad4168..0f53f1ea52aa 100644 --- a/unotools/source/config/cmdoptions.cxx +++ b/unotools/source/config/cmdoptions.cxx @@ -211,13 +211,16 @@ void SvtCommandOptions_Impl::Notify( const Sequence< OUString >& ) // don't forget to update all existing frames and her might cached dispatch objects! // But look for already killed frames. We hold weak references instead of hard ones ... - for (SvtFrameVector::const_iterator pIt = m_lFrames.begin(); - pIt != m_lFrames.end(); - ++pIt ) + for (SvtFrameVector::iterator pIt = m_lFrames.begin(); pIt != m_lFrames.end(); ) { css::uno::Reference< css::frame::XFrame > xFrame(pIt->get(), css::uno::UNO_QUERY); if (xFrame.is()) + { xFrame->contextChanged(); + ++pIt; + } + else + pIt = m_lFrames.erase(pIt); } } diff --git a/unotools/source/config/eventcfg.cxx b/unotools/source/config/eventcfg.cxx index 82907d5fb7d8..0f968a85e22a 100644 --- a/unotools/source/config/eventcfg.cxx +++ b/unotools/source/config/eventcfg.cxx @@ -146,13 +146,16 @@ void GlobalEventConfig_Impl::Notify( const Sequence< OUString >& ) // don't forget to update all existing frames and her might cached dispatch objects! // But look for already killed frames. We hold weak references instead of hard ones ... - for (FrameVector::const_iterator pIt = m_lFrames.begin(); - pIt != m_lFrames.end(); - ++pIt ) + for (FrameVector::iterator pIt = m_lFrames.begin(); pIt != m_lFrames.end(); ) { css::uno::Reference< css::frame::XFrame > xFrame(pIt->get(), css::uno::UNO_QUERY); if (xFrame.is()) + { xFrame->contextChanged(); + ++pIt; + } + else + pIt = m_lFrames.erase(pIt); } } -- cgit v1.2.3