From 0c1172b17d68cccd19c7551916857fe8ae9ac092 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Tue, 15 May 2018 15:50:59 -0700 Subject: [PATCH] Garbage collection optimization We only need to iterate over the anchors when there are items that are marked invalid. We check once in the item list and only if there are invalid items to remove do we trim the anchor lists. However, the connected items might still need to be trimmed, so we leave this final step outside of the conditional. --- pcbnew/connectivity_algo.cpp | 45 +++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/pcbnew/connectivity_algo.cpp b/pcbnew/connectivity_algo.cpp index 29e650acd4..bb5b66bcb7 100644 --- a/pcbnew/connectivity_algo.cpp +++ b/pcbnew/connectivity_algo.cpp @@ -443,6 +443,9 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones ) printf("Search start\n"); #endif +#ifdef PROFILE + PROF_COUNTER garbage_collection( "garbage-collection" ); +#endif std::vector garbage; garbage.reserve( 1024 ); @@ -471,10 +474,10 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones ) #endif #ifdef PROFILE + garbage_collection.Show(); PROF_COUNTER search_cnt( "search-connections" ); PROF_COUNTER search_basic( "search-basic" ); PROF_COUNTER search_pads( "search-pads" ); - PROF_COUNTER search_tracks( "search-tracks" ); #endif if( m_padList.IsDirty() || m_trackList.IsDirty() || m_viaList.IsDirty() ) @@ -492,6 +495,7 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones ) } #ifdef PROFILE search_pads.Show(); + PROF_COUNTER search_tracks( "search-tracks" ); #endif for( auto& trackItem : m_trackList ) @@ -604,23 +608,8 @@ void CN_ITEM::RemoveInvalidRefs() void CN_LIST::RemoveInvalidItems( std::vector& aGarbage ) { - auto lastAnchor = std::remove_if(m_anchors.begin(), m_anchors.end(), - [] ( const CN_ANCHOR_PTR anchor ) { - return !anchor->Valid(); - } ); - - m_anchors.resize( lastAnchor - m_anchors.begin() ); - for( auto i = 0; i < PCB_LAYER_ID_COUNT; i++ ) + auto lastItem = std::remove_if(m_items.begin(), m_items.end(), [&aGarbage] ( CN_ITEM* item ) { - lastAnchor = std::remove_if(m_layer_anchors[i].begin(), m_layer_anchors[i].end(), - [] ( const CN_ANCHOR_PTR anchor ) { - return !anchor->Valid(); - } ); - - m_layer_anchors[i].resize( lastAnchor - m_layer_anchors[i].begin() ); - } - - auto lastItem = std::remove_if(m_items.begin(), m_items.end(), [&aGarbage] ( CN_ITEM* item ) { if( !item->Valid() ) { aGarbage.push_back ( item ); @@ -630,10 +619,28 @@ void CN_LIST::RemoveInvalidItems( std::vector& aGarbage ) return false; } ); - m_items.resize( lastItem - m_items.begin() ); + if( lastItem != m_items.end()) + { + auto lastAnchor = std::remove_if(m_anchors.begin(), m_anchors.end(), + [] ( const CN_ANCHOR_PTR anchor ) { + return !anchor->Valid(); + } ); + + m_anchors.resize( lastAnchor - m_anchors.begin() ); + for( auto i = 0; i < PCB_LAYER_ID_COUNT; i++ ) + { + lastAnchor = std::remove_if(m_layer_anchors[i].begin(), m_layer_anchors[i].end(), + [] ( const CN_ANCHOR_PTR anchor ) { + return !anchor->Valid(); + } ); + + m_layer_anchors[i].resize( lastAnchor - m_layer_anchors[i].begin() ); + } + + m_items.resize( lastItem - m_items.begin() ); + } // fixme: mem leaks - for( auto item : m_items ) item->RemoveInvalidRefs(); }