improve performance of CONNECTIVITY_DATA::GetNetItems

- CN_CONNECTIVITY_ALGO::ForEachItem
move implementation to header, so that a lambda can be inlined by the
compiler.  improves iteration performance x2

- CN_ITEM::Net
move implementation to header, so that it can be inlined by the
compiler.

- CONNECTIVITY_DATA::GetNetItems
don't use std::set to filter out duplicates.  use std::unique on sorted
vector.  use a bitset to perform type check.
This commit is contained in:
Oleg Endo 2020-04-13 03:59:13 +09:00 committed by Jon Evans
parent 83cb9c0d14
commit 3de5b98316
5 changed files with 26 additions and 39 deletions

View File

@ -747,14 +747,6 @@ void CN_CONNECTIVITY_ALGO::Clear()
}
void CN_CONNECTIVITY_ALGO::ForEachItem( const std::function<void( CN_ITEM& )>& aFunc )
{
for( auto item : m_itemList )
aFunc( *item );
}
void CN_CONNECTIVITY_ALGO::ForEachAnchor( const std::function<void( CN_ANCHOR& )>& aFunc )
{
ForEachItem( [aFunc] ( CN_ITEM& item ) {

View File

@ -248,7 +248,14 @@ public:
CN_LIST& ItemList() { return m_itemList; }
void ForEachAnchor( const std::function<void( CN_ANCHOR& )>& aFunc );
void ForEachItem( const std::function<void( CN_ITEM& )>& aFunc );
template <typename Func>
void ForEachItem( Func&& aFunc )
{
for( auto&& item : m_itemList )
aFunc( *item );
}
void MarkNetAsDirty( int aNet );
void SetProgressReporter( PROGRESS_REPORTER* aReporter );

View File

@ -383,31 +383,25 @@ const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetNetItems( int aNetCode,
const KICAD_T aTypes[] ) const
{
std::set<BOARD_CONNECTED_ITEM*> items;
std::vector<BOARD_CONNECTED_ITEM*> rv;
std::vector<BOARD_CONNECTED_ITEM*> items;
items.reserve( 32 );
m_connAlgo->ForEachItem( [&items, aNetCode, &aTypes] ( CN_ITEM& aItem )
std::bitset<MAX_STRUCT_TYPE_ID> type_bits;
for( unsigned int i = 0; aTypes[i] != EOT; ++i )
{
if( aItem.Valid() && ( aItem.Net() == aNetCode ) )
{
KICAD_T itemType = aItem.Parent()->Type();
wxASSERT( aTypes[i] < MAX_STRUCT_TYPE_ID );
type_bits.set( aTypes[i] );
}
for( int i = 0; aTypes[i] > 0; ++i )
{
wxASSERT( aTypes[i] < MAX_STRUCT_TYPE_ID );
if( itemType == aTypes[i] )
{
items.insert( aItem.Parent() );
break;
}
}
}
m_connAlgo->ForEachItem( [&]( CN_ITEM& aItem ) {
if( aItem.Valid() && ( aItem.Net() == aNetCode ) && type_bits[aItem.Parent()->Type()] )
items.push_back( aItem.Parent() );
} );
std::copy( items.begin(), items.end(), std::back_inserter( rv ) );
return rv;
std::sort( items.begin(), items.end() );
items.erase( std::unique( items.begin(), items.end() ), items.end() );
return items;
}

View File

@ -144,15 +144,6 @@ const VECTOR2I CN_ITEM::GetAnchor( int n ) const
}
int CN_ITEM::Net() const
{
if( !m_parent || !m_valid )
return -1;
return m_parent->GetNetCode();
}
void CN_ITEM::Dump()
{
printf(" valid: %d, connected: \n", !!Valid());

View File

@ -336,7 +336,10 @@ public:
virtual int AnchorCount() const;
virtual const VECTOR2I GetAnchor( int n ) const;
int Net() const;
int Net() const
{
return ( !m_parent || !m_valid ) ? -1 : m_parent->GetNetCode();
}
};
typedef std::shared_ptr<CN_ITEM> CN_ITEM_PTR;