Performance for large hierarchies: lazy eval

Don't create SCH_SHEET_LISTs until we have to, and then
only create them once.
This commit is contained in:
Jeff Young 2024-06-06 11:34:54 +01:00
parent e543ff0578
commit 44c588f122
5 changed files with 24 additions and 16 deletions

View File

@ -486,6 +486,7 @@ void SCH_COMMIT::Revert()
KIGFX::VIEW* view = m_toolMgr->GetView();
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( m_toolMgr->GetToolHolder() );
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
SCH_SHEET_LIST sheets;
if( m_changes.empty() )
return;
@ -564,7 +565,11 @@ void SCH_COMMIT::Revert()
if( field->GetId() == REFERENCE_FIELD )
{
SCH_SHEET_PATH sheet = schematic->GetSheets().FindSheetForScreen( screen );
// Lazy eval of sheet list; this is expensive even when unsorted
if( sheets.empty() )
sheets = schematic->GetUnorderedSheets();
SCH_SHEET_PATH sheet = sheets.FindSheetForScreen( screen );
symbol->SetRef( &sheet, field->GetText() );
}
}

View File

@ -109,7 +109,7 @@ wxString SCH_MARKER::SerializeToString() const
}
SCH_MARKER* SCH_MARKER::DeserializeFromString( SCHEMATIC* schematic, const wxString& data )
SCH_MARKER* SCH_MARKER::DeserializeFromString( const SCH_SHEET_LIST aSheetList, const wxString& data )
{
wxArrayString props = wxSplit( data, '|' );
VECTOR2I markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ),
@ -132,13 +132,11 @@ SCH_MARKER* SCH_MARKER::DeserializeFromString( SCHEMATIC* schematic, const wxStr
{
isLegacyMarker = false;
SCH_SHEET_LIST sheetPaths = schematic->GetSheets();
if( !props[5].IsEmpty() )
{
KIID_PATH sheetSpecificKiidPath( props[5] );
std::optional<SCH_SHEET_PATH> sheetSpecificPath =
sheetPaths.GetSheetPathByKIIDPath( sheetSpecificKiidPath, true );
aSheetList.GetSheetPathByKIIDPath( sheetSpecificKiidPath, true );
if( sheetSpecificPath.has_value() )
ercItem->SetSheetSpecificPath( sheetSpecificPath.value() );
}
@ -147,7 +145,7 @@ SCH_MARKER* SCH_MARKER::DeserializeFromString( SCHEMATIC* schematic, const wxStr
{
KIID_PATH mainItemKiidPath( props[6] );
std::optional<SCH_SHEET_PATH> mainItemPath =
sheetPaths.GetSheetPathByKIIDPath( mainItemKiidPath, true );
aSheetList.GetSheetPathByKIIDPath( mainItemKiidPath, true );
if( mainItemPath.has_value() )
{
if( props[7].IsEmpty() )
@ -158,7 +156,7 @@ SCH_MARKER* SCH_MARKER::DeserializeFromString( SCHEMATIC* schematic, const wxStr
{
KIID_PATH auxItemKiidPath( props[7] );
std::optional<SCH_SHEET_PATH> auxItemPath =
sheetPaths.GetSheetPathByKIIDPath( auxItemKiidPath, true );
aSheetList.GetSheetPathByKIIDPath( auxItemKiidPath, true );
if( auxItemPath.has_value() )
ercItem->SetItemsSheetPaths( mainItemPath.value(), auxItemPath.value() );

View File

@ -54,7 +54,7 @@ public:
void SwapData( SCH_ITEM* aItem ) override;
wxString SerializeToString() const;
static SCH_MARKER* DeserializeFromString( SCHEMATIC* schematic, const wxString& data );
static SCH_MARKER* DeserializeFromString( const SCH_SHEET_LIST aSheetList, const wxString& data );
void ViewGetLayers( int aLayers[], int& aCount ) const override;

View File

@ -274,6 +274,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
bool dirtyConnectivity = false;
bool rebuildHierarchyNavigator = false;
SCH_CLEANUP_FLAGS connectivityCleanUp = NO_CLEANUP;
SCH_SHEET_LIST sheets;
// Undo in the reverse order of list creation: (this can allow stacked changes like the
// same item can be changed and deleted in the same complex command).
@ -371,7 +372,11 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
}
else if( status == UNDO_REDO::PAGESETTINGS )
{
SCH_SHEET_PATH undoSheet = m_schematic->GetSheets().FindSheetForScreen( screen );
// Lazy eval of sheet list; this is expensive even when unsorted
if( sheets.empty() )
sheets = m_schematic->GetUnorderedSheets();
SCH_SHEET_PATH undoSheet = sheets.FindSheetForScreen( screen );
if( GetCurrentSheet() != undoSheet )
{
@ -428,7 +433,11 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
if( field->GetId() == REFERENCE_FIELD )
{
SCH_SHEET_PATH sheet = m_schematic->GetSheets().FindSheetForScreen( screen );
// Lazy eval of sheet list; this is expensive even when unsorted
if( sheets.empty() )
sheets = m_schematic->GetUnorderedSheets();
SCH_SHEET_PATH sheet = sheets.FindSheetForScreen( screen );
symbol->SetRef( &sheet, field->GetText() );
}

View File

@ -324,7 +324,6 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
SCH_SHEET_LIST sheets = m_frame->Schematic().GetSheets();
SYMBOL_LIB_TABLE* libs = PROJECT_SCH::SchSymbolLibTable( &m_frame->Prj() );
SYMBOL_LIB* cache = PROJECT_SCH::SchLibs( &m_frame->Prj() )->GetCacheLibrary();
@ -336,13 +335,10 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
std::set<LIB_SYMBOL*, decltype( compareByLibID )> part_list( compareByLibID );
for( SCH_SHEET_PATH& sheet : sheets )
for( SCH_SHEET_PATH& sheet : hierarchy )
{
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
{
if( item->Type() != SCH_SYMBOL_T )
continue;
SCH_SYMBOL* s = static_cast<SCH_SYMBOL*>( item );
LIB_SYMBOL* libSymbol = SchGetLibSymbol( s->GetLibId(), libs, cache );