Performance improvements.

Don't construct a wxString or a LSEQ when you don't
have to.  They're both more expensive than you might
think.
This commit is contained in:
Jeff Young 2024-06-12 11:05:56 +01:00
parent 63cd110720
commit 694a7db457
13 changed files with 181 additions and 132 deletions

View File

@ -83,8 +83,11 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags )
hash_combine( ret, via->TopLayer() ); hash_combine( ret, via->TopLayer() );
hash_combine( ret, via->BottomLayer() ); hash_combine( ret, via->BottomLayer() );
for( PCB_LAYER_ID layer : via->GetLayerSet().Seq() ) via->GetLayerSet().RunOnLayers(
[&]( PCB_LAYER_ID layer )
{
hash_combine( ret, via->FlashLayer( layer ) ); hash_combine( ret, via->FlashLayer( layer ) );
} );
break; break;
} }
@ -102,8 +105,11 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags )
hash_combine( ret, pad->GetDrillSizeX(), pad->GetDrillSizeY() ); hash_combine( ret, pad->GetDrillSizeX(), pad->GetDrillSizeY() );
hash_combine( ret, pad->GetDrillShape() ); hash_combine( ret, pad->GetDrillShape() );
for( PCB_LAYER_ID layer : pad->GetLayerSet().Seq() ) pad->GetLayerSet().RunOnLayers(
[&]( PCB_LAYER_ID layer )
{
hash_combine( ret, pad->FlashLayer( layer ) ); hash_combine( ret, pad->FlashLayer( layer ) );
} );
} }
hash_combine( ret, pad->GetSize().x, pad->GetSize().y ); hash_combine( ret, pad->GetSize().x, pad->GetSize().y );

View File

@ -815,6 +815,18 @@ public:
*/ */
LSEQ SeqStackupForPlotting() const; LSEQ SeqStackupForPlotting() const;
/**
* Execute a function on each layer of the LSET.
*/
void RunOnLayers( const std::function<void( PCB_LAYER_ID )>& aFunction ) const
{
for( size_t ii = 0; ii < size(); ++ii )
{
if( test( ii ) )
aFunction( PCB_LAYER_ID( ii ) );
}
}
/** /**
* Return a hex string showing contents of this LSEQ. * Return a hex string showing contents of this LSEQ.
*/ */

View File

@ -132,16 +132,20 @@ wxString BOARD_CONNECTED_ITEM::GetNetnameMsg() const
} }
wxString BOARD_CONNECTED_ITEM::GetShortNetname() const const wxString& BOARD_CONNECTED_ITEM::GetShortNetname() const
{ {
return m_netinfo ? m_netinfo->GetShortNetname() : wxString(); static wxString emptyString;
return m_netinfo ? m_netinfo->GetShortNetname() : emptyString;
} }
wxString BOARD_CONNECTED_ITEM::GetDisplayNetname() const const wxString& BOARD_CONNECTED_ITEM::GetDisplayNetname() const
{ {
static wxString emptyString;
if( !m_netinfo ) if( !m_netinfo )
return wxString(); return emptyString;
if( const BOARD* board = GetBoard() ) if( const BOARD* board = GetBoard() )
{ {

View File

@ -124,12 +124,12 @@ public:
/** /**
* @return the short netname. * @return the short netname.
*/ */
wxString GetShortNetname() const; const wxString& GetShortNetname() const;
/** /**
* @return the unescaped short netname. * @return the unescaped short netname.
*/ */
wxString GetDisplayNetname() const; const wxString& GetDisplayNetname() const;
/** /**
* Return an item's "own" clearance in internal units. * Return an item's "own" clearance in internal units.

View File

@ -200,11 +200,12 @@ bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem )
BOARD* board = zone->GetBoard(); BOARD* board = zone->GetBoard();
LSET layerset = board->GetEnabledLayers() & zone->GetLayerSet(); LSET layerset = board->GetEnabledLayers() & zone->GetLayerSet();
for( PCB_LAYER_ID layer : layerset.Seq() ) layerset.RunOnLayers(
[&]( PCB_LAYER_ID layer )
{ {
for( CN_ITEM* zitem : m_itemList.Add( zone, layer ) ) for( CN_ITEM* zitem : m_itemList.Add( zone, layer ) )
m_itemMap[zone].Link( zitem ); m_itemMap[zone].Link( zitem );
} } );
} }
break; break;
@ -456,11 +457,12 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
BOARD* board = zone->GetBoard(); BOARD* board = zone->GetBoard();
LSET layerset = board->GetEnabledLayers() & zone->GetLayerSet() & LSET::AllCuMask(); LSET layerset = board->GetEnabledLayers() & zone->GetLayerSet() & LSET::AllCuMask();
for( PCB_LAYER_ID layer : layerset.Seq() ) layerset.RunOnLayers(
[&]( PCB_LAYER_ID layer )
{ {
for( int j = 0; j < zone->GetFilledPolysList( layer )->OutlineCount(); j++ ) for( int j = 0; j < zone->GetFilledPolysList( layer )->OutlineCount(); j++ )
zitems.push_back( new CN_ZONE_LAYER( zone, layer, j ) ); zitems.push_back( new CN_ZONE_LAYER( zone, layer, j ) );
} } );
} }
} }
@ -899,8 +901,11 @@ bool CN_VISITOR::operator()( CN_ITEM* aCandidate )
LSET commonLayers = parentA->GetLayerSet() & parentB->GetLayerSet(); LSET commonLayers = parentA->GetLayerSet() & parentB->GetLayerSet();
for( PCB_LAYER_ID layer : commonLayers.Seq() ) for( size_t ii = 0; ii < commonLayers.size(); ++ii )
{ {
if( commonLayers.test( ii ) )
{
PCB_LAYER_ID layer = PCB_LAYER_ID( ii );
FLASHING flashingA = FLASHING::NEVER_FLASHED; FLASHING flashingA = FLASHING::NEVER_FLASHED;
FLASHING flashingB = FLASHING::NEVER_FLASHED; FLASHING flashingB = FLASHING::NEVER_FLASHED;
@ -934,6 +939,7 @@ bool CN_VISITOR::operator()( CN_ITEM* aCandidate )
return true; return true;
} }
} }
}
return true; return true;
}; };

View File

@ -111,11 +111,11 @@ bool DRC_CACHE_GENERATOR::Run()
copperLayers = boardCopperLayers; copperLayers = boardCopperLayers;
} }
for( PCB_LAYER_ID layer : copperLayers.Seq() ) copperLayers.RunOnLayers(
[&]( PCB_LAYER_ID layer )
{ {
if( IsCopperLayer( layer ) )
m_board->m_CopperItemRTreeCache->Insert( item, layer, largestClearance ); m_board->m_CopperItemRTreeCache->Insert( item, layer, largestClearance );
} } );
done.fetch_add( 1 ); done.fetch_add( 1 );
return true; return true;
@ -179,11 +179,12 @@ bool DRC_CACHE_GENERATOR::Run()
{ {
std::unique_ptr<DRC_RTREE> rtree = std::make_unique<DRC_RTREE>(); std::unique_ptr<DRC_RTREE> rtree = std::make_unique<DRC_RTREE>();
for( PCB_LAYER_ID layer : aZone->GetLayerSet().Seq() ) aZone->GetLayerSet().RunOnLayers(
[&]( PCB_LAYER_ID layer )
{ {
if( IsCopperLayer( layer ) ) if( IsCopperLayer( layer ) )
rtree->Insert( aZone, layer ); rtree->Insert( aZone, layer );
} } );
{ {
std::unique_lock<std::shared_mutex> writeLock( m_board->m_CachesMutex ); std::unique_lock<std::shared_mutex> writeLock( m_board->m_CachesMutex );
@ -218,8 +219,11 @@ bool DRC_CACHE_GENERATOR::Run()
{ {
if( !zone->GetIsRuleArea() && !zone->IsTeardropArea() ) if( !zone->GetIsRuleArea() && !zone->IsTeardropArea() )
{ {
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) zone->GetLayerSet().RunOnLayers(
[&]( PCB_LAYER_ID layer )
{
m_board->m_ZoneIsolatedIslandsMap[ zone ][ layer ] = ISOLATED_ISLANDS(); m_board->m_ZoneIsolatedIslandsMap[ zone ][ layer ] = ISOLATED_ISLANDS();
} );
} }
} }

View File

@ -134,8 +134,12 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
if( zoneRTree ) if( zoneRTree )
{ {
for( PCB_LAYER_ID layer : ruleArea->GetLayerSet().Seq() ) for( size_t ii = 0; ii < ruleArea->GetLayerSet().size(); ++ii )
{ {
if( ruleArea->GetLayerSet().test( ii ) )
{
PCB_LAYER_ID layer = PCB_LAYER_ID( ii );
if( zoneRTree->QueryColliding( areaBBox, &areaPoly, layer ) ) if( zoneRTree->QueryColliding( areaBBox, &areaPoly, layer ) )
{ {
isInside = true; isInside = true;
@ -147,6 +151,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
} }
} }
} }
}
if( m_drcEngine->IsCancelled() ) if( m_drcEngine->IsCancelled() )
return 0; return 0;
@ -217,7 +222,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS ); std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
DRC_RULE* rule = constraint.GetParentRule(); DRC_RULE* rule = constraint.GetParentRule();
VECTOR2I pos = item->GetPosition(); VECTOR2I pos = item->GetPosition();
PCB_LAYER_ID layer = UNDEFINED_LAYER; PCB_LAYER_ID layer = item->GetLayerSet().ExtractLayer();
wxString msg; wxString msg;
msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ), constraint.GetName() ); msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ), constraint.GetName() );
@ -226,9 +231,6 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
drcItem->SetItems( item ); drcItem->SetItems( item );
drcItem->SetViolatingRule( rule ); drcItem->SetViolatingRule( rule );
if( item->GetLayerSet().count() )
layer = item->GetLayerSet().Seq().front();
if( rule->m_Implicit ) if( rule->m_Implicit )
{ {
// Provide a better location for keepout area collisions. // Provide a better location for keepout area collisions.

View File

@ -572,7 +572,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
{ {
// For single-layer objects, exclude all layers including ancillary layers // For single-layer objects, exclude all layers including ancillary layers
// such as holes, netnames, etc. // such as holes, netnames, etc.
PCB_LAYER_ID singleLayer = item->GetLayerSet().Seq()[0]; PCB_LAYER_ID singleLayer = item->GetLayerSet().ExtractLayer();
if( parentFP->GetPrivateLayers().test( singleLayer ) ) if( parentFP->GetPrivateLayers().test( singleLayer ) )
return false; return false;

View File

@ -908,12 +908,12 @@ void PCB_VIA::SetLayerSet( LSET aLayerSet )
{ {
bool first = true; bool first = true;
for( PCB_LAYER_ID layer : aLayerSet.Seq() ) aLayerSet.RunOnLayers(
[&]( PCB_LAYER_ID layer )
{
// m_layer and m_bottomLayer are copper layers, so consider only copper layers
if( IsCopperLayer( layer ) )
{ {
// m_layer and m_bottomLayer are copper layers, so consider only copper layers in aLayerSet
if( !IsCopperLayer( layer ) )
continue;
if( first ) if( first )
{ {
Padstack().Drill().start = layer; Padstack().Drill().start = layer;
@ -922,6 +922,7 @@ void PCB_VIA::SetLayerSet( LSET aLayerSet )
Padstack().Drill().end = layer; Padstack().Drill().end = layer;
} }
} );
} }
@ -995,11 +996,16 @@ void PCB_VIA::SanitizeLayers()
bool PCB_VIA::FlashLayer( LSET aLayers ) const bool PCB_VIA::FlashLayer( LSET aLayers ) const
{ {
for( PCB_LAYER_ID layer : aLayers.Seq() ) for( size_t ii = 0; ii < aLayers.size(); ++ii )
{ {
if( aLayers.test( ii ) )
{
PCB_LAYER_ID layer = PCB_LAYER_ID( ii );
if( FlashLayer( layer ) ) if( FlashLayer( layer ) )
return true; return true;
} }
}
return false; return false;
} }
@ -1116,18 +1122,16 @@ double PCB_TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
return HIDE; return HIDE;
} }
// Pick the approximate size of the netname (square chars)
wxString netName = GetDisplayNetname();
size_t num_chars = netName.size();
if( GetLength() < num_chars * GetWidth() )
return HIDE;
// When drawing netnames, clip the track to the viewport
VECTOR2I start( GetStart() ); VECTOR2I start( GetStart() );
VECTOR2I end( GetEnd() ); VECTOR2I end( GetEnd() );
BOX2D viewport = aView->GetViewport();
BOX2I clipBox = BOX2ISafe( viewport ); // Calc the approximate size of the netname (assume square chars)
SEG::ecoord nameSize = GetDisplayNetname().size() * GetWidth();
if( VECTOR2I( end - start ).SquaredEuclideanNorm() < nameSize * nameSize )
return HIDE;
BOX2I clipBox = BOX2ISafe( aView->GetViewport() );
ClipLine( &clipBox, start.x, start.y, end.x, end.y ); ClipLine( &clipBox, start.x, start.y, end.x, end.y );

View File

@ -528,8 +528,12 @@ bool collidesWithArea( BOARD_ITEM* aItem, PCBEXPR_CONTEXT* aCtx, ZONE* aArea )
if( zoneRTree ) if( zoneRTree )
{ {
for( PCB_LAYER_ID layer : aArea->GetLayerSet().Seq() ) for( size_t ii = 0; ii < aArea->GetLayerSet().size(); ++ii )
{ {
if( aArea->GetLayerSet().test( ii ) )
{
PCB_LAYER_ID layer = PCB_LAYER_ID( ii );
if( aCtx->GetLayer() == layer || aCtx->GetLayer() == UNDEFINED_LAYER ) if( aCtx->GetLayer() == layer || aCtx->GetLayer() == UNDEFINED_LAYER )
{ {
if( zoneRTree->QueryColliding( areaBBox, &areaOutline, layer ) ) if( zoneRTree->QueryColliding( areaBBox, &areaOutline, layer ) )
@ -537,6 +541,7 @@ bool collidesWithArea( BOARD_ITEM* aItem, PCBEXPR_CONTEXT* aCtx, ZONE* aArea )
} }
} }
} }
}
return false; return false;
} }

View File

@ -102,11 +102,12 @@ void RATSNEST_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
} }
else else
{ {
for( PCB_LAYER_ID layer : LSET::AllCuMask().Seq() ) LSET::AllCuMask().RunOnLayers(
[&]( PCB_LAYER_ID layer )
{ {
if( aView->IsLayerVisible( layer ) ) if( aView->IsLayerVisible( layer ) )
visibleLayers.set( layer ); visibleLayers.set( layer );
} } );
} }
auto adjustColor = auto adjustColor =

View File

@ -246,8 +246,11 @@ int ZONE_FILLER_TOOL::ZoneFillDirty( const TOOL_EVENT& aEvent )
for( ZONE* zone : toFill ) for( ZONE* zone : toFill )
{ {
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) zone->GetLayerSet().RunOnLayers(
[&]( PCB_LAYER_ID layer )
{
pts += zone->GetFilledPolysList( layer )->FullPointCount(); pts += zone->GetFilledPolysList( layer )->FullPointCount();
} );
if( pts > 1000 ) if( pts > 1000 )
{ {

View File

@ -150,7 +150,8 @@ void ZONE::InitDataFromSrcInCopyCtor( const ZONE& aZone )
delete m_CornerSelection; delete m_CornerSelection;
m_CornerSelection = nullptr; m_CornerSelection = nullptr;
for( PCB_LAYER_ID layer : aZone.GetLayerSet().Seq() ) aZone.GetLayerSet().RunOnLayers(
[&]( PCB_LAYER_ID layer )
{ {
std::shared_ptr<SHAPE_POLY_SET> fill = aZone.m_FilledPolysList.at( layer ); std::shared_ptr<SHAPE_POLY_SET> fill = aZone.m_FilledPolysList.at( layer );
@ -161,7 +162,7 @@ void ZONE::InitDataFromSrcInCopyCtor( const ZONE& aZone )
m_filledPolysHash[layer] = aZone.m_filledPolysHash.at( layer ); m_filledPolysHash[layer] = aZone.m_filledPolysHash.at( layer );
m_insulatedIslands[layer] = aZone.m_insulatedIslands.at( layer ); m_insulatedIslands[layer] = aZone.m_insulatedIslands.at( layer );
} } );
m_borderStyle = aZone.m_borderStyle; m_borderStyle = aZone.m_borderStyle;
m_borderHatchPitch = aZone.m_borderHatchPitch; m_borderHatchPitch = aZone.m_borderHatchPitch;
@ -279,12 +280,13 @@ void ZONE::SetLayerSet( LSET aLayerSet )
m_filledPolysHash.clear(); m_filledPolysHash.clear();
m_insulatedIslands.clear(); m_insulatedIslands.clear();
for( PCB_LAYER_ID layer : aLayerSet.Seq() ) aLayerSet.RunOnLayers(
[&]( PCB_LAYER_ID layer )
{ {
m_FilledPolysList[layer] = std::make_shared<SHAPE_POLY_SET>(); m_FilledPolysList[layer] = std::make_shared<SHAPE_POLY_SET>();
m_filledPolysHash[layer] = {}; m_filledPolysHash[layer] = {};
m_insulatedIslands[layer] = {}; m_insulatedIslands[layer] = {};
} } );
} }
m_layerSet = aLayerSet; m_layerSet = aLayerSet;
@ -294,13 +296,13 @@ void ZONE::SetLayerSet( LSET aLayerSet )
void ZONE::ViewGetLayers( int aLayers[], int& aCount ) const void ZONE::ViewGetLayers( int aLayers[], int& aCount ) const
{ {
aCount = 0; aCount = 0;
LSEQ layers = m_layerSet.Seq();
for( PCB_LAYER_ID layer : m_layerSet.Seq() ) m_layerSet.RunOnLayers(
[&]( PCB_LAYER_ID layer )
{ {
aLayers[ aCount++ ] = layer; // For outline (always full opacity) aLayers[ aCount++ ] = layer;
aLayers[ aCount++ ] = layer + static_cast<int>( LAYER_ZONE_START ); // For fill (obeys global zone opacity) aLayers[ aCount++ ] = layer + static_cast<int>( LAYER_ZONE_START );
} } );
if( IsConflicting() ) if( IsConflicting() )
aLayers[ aCount++ ] = LAYER_CONFLICTS_SHADOW; aLayers[ aCount++ ] = LAYER_CONFLICTS_SHADOW;