A few performance improvements from profiling.

Most of them are very small; the removal of the Fracture() in
DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() is the only
significant one.
This commit is contained in:
Jeff Young 2023-09-29 21:54:59 +01:00
parent fa11e9138d
commit e1c51ed192
4 changed files with 63 additions and 59 deletions

View File

@ -85,7 +85,7 @@ SCH_SEXPR_PARSER::SCH_SEXPR_PARSER( LINE_READER* aLineReader, PROGRESS_REPORTER*
void SCH_SEXPR_PARSER::checkpoint() void SCH_SEXPR_PARSER::checkpoint()
{ {
const unsigned PROGRESS_DELTA = 250; const unsigned PROGRESS_DELTA = 500;
if( m_progressReporter ) if( m_progressReporter )
{ {

View File

@ -81,8 +81,9 @@ bool DRC_CACHE_GENERATOR::Run()
} }
} }
// This is the number of tests between 2 calls to the progress bar // This is the number of tests between 2 calls to the progress bar.
size_t progressDelta = 200; // Note that zones are -not- done here, so it's reasonably fast.
size_t progressDelta = 500;
size_t count = 0; size_t count = 0;
size_t ii = 0; size_t ii = 0;

View File

@ -1144,70 +1144,73 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
poly_segments.resize( m_board->m_DRCCopperZones.size() ); poly_segments.resize( m_board->m_DRCCopperZones.size() );
// Contains the index for zoneA, zoneB, the conflict point, the actual clearance, the required clearance, and the layer // Contains the index for zoneA, zoneB, the conflict point, the actual clearance, the
// required clearance, and the layer
using report_data = std::tuple<int, int, VECTOR2I, int, int, PCB_LAYER_ID>; using report_data = std::tuple<int, int, VECTOR2I, int, int, PCB_LAYER_ID>;
const int invalid_zone = -1; const int invalid_zone = -1;
std::vector<std::future<report_data>> futures; std::vector<std::future<report_data>> futures;
thread_pool& tp = GetKiCadThreadPool(); thread_pool& tp = GetKiCadThreadPool();
auto checkZones = [testClearance, testIntersects, &poly_segments, &cancelled, invalid_zone] auto checkZones =
( int zoneA, int zoneB, [testClearance, testIntersects, &poly_segments, &cancelled, invalid_zone]
int zone2zoneClearance, PCB_LAYER_ID layer ) -> report_data ( int zoneA, int zoneB, int clearance, PCB_LAYER_ID layer ) -> report_data
{
// Iterate through all the segments of refSmoothedPoly
std::map<VECTOR2I, int> conflictPoints;
std::vector<SEG>& refSegments = poly_segments[zoneA][layer];
std::vector<SEG>& testSegments = poly_segments[zoneB][layer];
bool reported = false;
auto invalid_result = std::make_tuple( invalid_zone, invalid_zone, VECTOR2I(), 0, 0, F_Cu );
for( SEG& refSegment : refSegments )
{
int ax1 = refSegment.A.x;
int ay1 = refSegment.A.y;
int ax2 = refSegment.B.x;
int ay2 = refSegment.B.y;
// Iterate through all the segments in smoothed_polys[ia2]
for( SEG& testSegment : testSegments )
{ {
// Build test segment // Iterate through all the segments of refSmoothedPoly
VECTOR2I pt; std::map<VECTOR2I, int> conflictPoints;
int bx1 = testSegment.A.x; std::vector<SEG>& refSegments = poly_segments[zoneA][layer];
int by1 = testSegment.A.y; std::vector<SEG>& testSegments = poly_segments[zoneB][layer];
int bx2 = testSegment.B.x; bool reported = false;
int by2 = testSegment.B.y; auto invalid_result = std::make_tuple( invalid_zone, invalid_zone, VECTOR2I(),
0, 0, F_Cu );
// We have ensured that the A segment starts before the B segment, so if the for( SEG& refSegment : refSegments )
// A segment ends before the B segment starts, we can skip to the next A
if( ax2 < bx1 )
break;
int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0,
ax1, ay1, ax2, ay2, 0,
zone2zoneClearance, &pt.x, &pt.y );
if( d < zone2zoneClearance )
{ {
if( d == 0 && testIntersects ) int ax1 = refSegment.A.x;
reported = true; int ay1 = refSegment.A.y;
else if( testClearance ) int ax2 = refSegment.B.x;
reported = true; int ay2 = refSegment.B.y;
if( reported ) // Iterate through all the segments in smoothed_polys[ia2]
return std::make_tuple( zoneA, zoneB, pt, d, zone2zoneClearance, layer ); for( SEG& testSegment : testSegments )
{
// Build test segment
VECTOR2I pt;
int bx1 = testSegment.A.x;
int by1 = testSegment.A.y;
int bx2 = testSegment.B.x;
int by2 = testSegment.B.y;
// We have ensured that the 'A' segment starts before the 'B' segment,
// so if the 'A' segment ends before the 'B' segment starts, we can skip
// to the next 'A'
if( ax2 < bx1 )
break;
int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0,
ax1, ay1, ax2, ay2, 0,
clearance, &pt.x, &pt.y );
if( d < clearance )
{
if( d == 0 && testIntersects )
reported = true;
else if( testClearance )
reported = true;
if( reported )
return std::make_tuple( zoneA, zoneB, pt, d, clearance, layer );
}
if( cancelled )
return invalid_result;
}
} }
if( cancelled ) return invalid_result;
return invalid_result; };
}
}
return invalid_result;
};
for( int layer_id = F_Cu; layer_id <= B_Cu; ++layer_id ) for( int layer_id = F_Cu; layer_id <= B_Cu; ++layer_id )
{ {
@ -1222,11 +1225,9 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
{ {
if( m_board->m_DRCCopperZones[ii]->IsOnLayer( layer ) ) if( m_board->m_DRCCopperZones[ii]->IsOnLayer( layer ) )
{ {
SHAPE_POLY_SET poly = SHAPE_POLY_SET poly = *m_board->m_DRCCopperZones[ii]->GetFilledPolysList( layer );
*m_board->m_DRCCopperZones[ii]->GetFilledPolysList( layer );
std::vector<SEG>& poly_segs = poly_segments[ii][layer]; std::vector<SEG>& poly_segs = poly_segments[ii][layer];
poly.Fracture( SHAPE_POLY_SET::PM_FAST );
poly.BuildBBoxCaches(); poly.BuildBBoxCaches();
poly_segs.reserve( poly.FullPointCount() ); poly_segs.reserve( poly.FullPointCount() );

View File

@ -1859,7 +1859,9 @@ int PCB_EDIT_FRAME::TestStandalone()
bool PCB_EDIT_FRAME::FetchNetlistFromSchematic( NETLIST& aNetlist, bool PCB_EDIT_FRAME::FetchNetlistFromSchematic( NETLIST& aNetlist,
const wxString& aAnnotateMessage ) const wxString& aAnnotateMessage )
{ {
if( TestStandalone() == 0 ) int standalone = TestStandalone();
if( standalone == 0 )
{ {
DisplayErrorMessage( this, _( "Cannot update the PCB because PCB editor is opened in " DisplayErrorMessage( this, _( "Cannot update the PCB because PCB editor is opened in "
"stand-alone mode. In order to create or update PCBs from " "stand-alone mode. In order to create or update PCBs from "
@ -1868,7 +1870,7 @@ bool PCB_EDIT_FRAME::FetchNetlistFromSchematic( NETLIST& aNetlist,
return false; // Not in standalone mode return false; // Not in standalone mode
} }
if( TestStandalone() < 0 ) // Problem with Eeschema or the schematic if( standalone < 0 ) // Problem with Eeschema or the schematic
return false; return false;
Raise(); // Show Raise(); // Show