7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 00:21:25 +00:00

Performance.

Saves about 30% of the time to open the sim model
dialog.  Pretty much all the remaining time is in PEGTL,
and that's even with short-circuiting it for most param
values.
This commit is contained in:
Jeff Young 2024-08-30 22:49:11 +01:00
parent ab1c179fa3
commit c22eac2fbf
15 changed files with 75 additions and 76 deletions

View File

@ -794,11 +794,9 @@ bool SIM_MODEL::PARAM::INFO::Matches( const std::string& aParamName ) const
int SIM_MODEL::doFindParam( const std::string& aParamName ) const
{
std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
for( int ii = 0; ii < (int) params.size(); ++ii )
for( int ii = 0; ii < (int) GetParamCount(); ++ii )
{
if( params[ii].get().Matches( aParamName ) )
if( GetParam( ii ).Matches( aParamName ) )
return ii;
}
@ -814,17 +812,6 @@ const SIM_MODEL::PARAM* SIM_MODEL::FindParam( const std::string& aParamName ) co
}
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> SIM_MODEL::GetParams() const
{
std::vector<std::reference_wrapper<const PARAM>> params;
for( int i = 0; i < GetParamCount(); ++i )
params.emplace_back( GetParam( i ) );
return params;
}
const SIM_MODEL::PARAM& SIM_MODEL::GetParamOverride( unsigned aParamIndex ) const
{
return m_params.at( aParamIndex );

View File

@ -485,8 +485,6 @@ public:
const PARAM* FindParam( const std::string& aParamName ) const;
std::vector<std::reference_wrapper<const PARAM>> GetParams() const;
const PARAM& GetParamOverride( unsigned aParamIndex ) const; // Return the actual parameter.
const PARAM& GetBaseParam( unsigned aParamIndex ) const; // Always return base parameter if it exists.

View File

@ -40,13 +40,6 @@ std::string SPICE_GENERATOR_IBIS::ModelLine( const SPICE_ITEM& aItem ) const
return "";
}
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> SPICE_GENERATOR_IBIS::GetInstanceParams() const
{
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> vec;
return vec;
}
std::vector<std::string> SPICE_GENERATOR_IBIS::CurrentNames( const SPICE_ITEM& aItem ) const
{
std::vector<std::string> currentNames;
@ -278,9 +271,9 @@ SIM_MODEL_IBIS::SIM_MODEL_IBIS( TYPE aType, const SIM_MODEL_IBIS& aSource ) :
{
for( PARAM& param1 : m_params )
{
for( auto& param2refwrap : aSource.GetParams() )
for( int ii = 0; ii < aSource.GetParamCount(); ++ii )
{
const PARAM& param2 = param2refwrap.get();
const PARAM& param2 = aSource.GetParam( ii );
if( param1.info.name == param2.info.name )
param1.value = param2.value;

View File

@ -44,9 +44,6 @@ public:
std::string IbisDevice( const SPICE_ITEM& aItem, const PROJECT& aProject,
const wxString& aCacheDir, REPORTER& aReporter ) const;
protected:
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> GetInstanceParams() const override;
};
class SIM_MODEL_IBIS : public SIM_MODEL

View File

@ -29,8 +29,15 @@ std::string SPICE_GENERATOR_L_MUTUAL::ItemParams() const
{
std::string result;
for( const SIM_MODEL::PARAM& param : GetInstanceParams() )
for( int ii = 0; ii < m_model.GetParamCount(); ++ii )
{
const SIM_MODEL::PARAM& param = m_model.GetParam( ii );
if( !param.info.isSpiceInstanceParam )
continue;
result.append( " " + SIM_VALUE::ToSpice( param.value ) );
}
return result;
}

View File

@ -85,11 +85,9 @@ int SIM_MODEL_NGSPICE::doFindParam( const std::string& aParamName ) const
{
// Special case to allow escaped model parameters (suffixed with "_")
std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
for( int ii = 0; ii < (int) params.size(); ++ii )
for( int ii = 0; ii < (int) GetParamCount(); ++ii )
{
const PARAM& param = params[ii];
const PARAM& param = GetParam( ii );
if( param.Matches( aParamName ) || param.Matches( aParamName + "_" ) )
return ii;
@ -111,16 +109,29 @@ void SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const std::string& aParamName,
// First we try to use the name as is. Note that you can't set instance parameters from this
// function, it's for ".model" cards, not for instantiations.
std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
for( int ii = 0; ii < (int) params.size(); ++ii )
for( int ii = 0; ii < (int) GetParamCount(); ++ii )
{
const PARAM& param = params[ii];
const PARAM& param = GetParam(ii);
if( param.info.isSpiceInstanceParam || param.info.category == PARAM::CATEGORY::SUPERFLUOUS )
continue;
if( param.Matches( aParamName ) || param.Matches( aParamName + "_" ) )
if( param.Matches( aParamName ) )
{
SetParamValue( ii, aValue, aNotation );
return;
}
}
for( int ii = 0; ii < (int) GetParamCount(); ++ii )
{
const PARAM& param = GetParam(ii);
if( param.info.isSpiceInstanceParam || param.info.category == PARAM::CATEGORY::SUPERFLUOUS )
continue;
if( param.info.name.ends_with( "_" )
&& boost::iequals( param.info.name, aParamName + "_" ) )
{
SetParamValue( ii, aValue, aNotation );
return;
@ -138,9 +149,9 @@ void SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const std::string& aParamName,
{
// Find an actual parameter with the same id. Even if the ngspiceParam was
// superfluous, its alias target might not be.
for( int ii = 0; ii < (int) params.size(); ++ii )
for( int ii = 0; ii < (int) GetParamCount(); ++ii )
{
const PARAM::INFO& paramInfo = params[ii].get().info;
const PARAM::INFO& paramInfo = GetParam( ii ).info;
if( paramInfo.category == PARAM::CATEGORY::SUPERFLUOUS )
continue;

View File

@ -101,8 +101,13 @@ std::string SPICE_GENERATOR_RAW_SPICE::ItemParams() const
{
std::string result;
for( const SIM_MODEL::PARAM& param : GetInstanceParams() )
for( int ii = 0; ii < m_model.GetParamCount(); ++ii )
{
const SIM_MODEL::PARAM& param = m_model.GetParam( ii );
if( !param.info.isSpiceInstanceParam )
continue;
if( param.info.name == "model" )
result.append( " " + SIM_VALUE::ToSpice( param.value ) );
}

View File

@ -175,8 +175,10 @@ std::string SPICE_GENERATOR_SOURCE::ItemLine( const SPICE_ITEM& aItem ) const
break;
default:
for( const SIM_MODEL::PARAM& param : m_model.GetParams() )
for( int ii = 0; ii < m_model.GetParamCount(); ++ii )
{
const SIM_MODEL::PARAM& param = m_model.GetParam( ii );
if( ac != "" && ( param.Matches( "ac" ) || param.Matches( "ph" ) ) )
continue;

View File

@ -31,8 +31,8 @@ SIM_MODEL_SPICE_FALLBACK::SIM_MODEL_SPICE_FALLBACK( TYPE aType, const std::strin
// Create the model we *should* have had to copy its parameter list
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( aType );
for( const SIM_MODEL::PARAM& param : model->GetParams() )
AddParam( param.info );
for( int ii = 0; ii < GetParamCount(); ++ii )
AddParam( GetParam( ii ).info );
m_spiceCode = aRawSpiceCode;
}
@ -66,11 +66,9 @@ int SIM_MODEL_SPICE_FALLBACK::doFindParam( const std::string& aParamName ) const
{
// Special case to allow escaped model parameters (suffixed with "_")
std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
for( int ii = 0; ii < (int) params.size(); ++ii )
for( int ii = 0; ii < GetParamCount(); ++ii )
{
const PARAM& param = params[ii];
const SIM_MODEL::PARAM& param = GetParam( ii );
if( param.Matches( aParamName ) || param.Matches( aParamName + "_" ) )
return ii;

View File

@ -151,8 +151,8 @@ void SIM_MODEL_SUBCKT::SetBaseModel( const SIM_MODEL& aBaseModel )
AddPin( pin );
// Same for parameters.
for( const PARAM& param : GetBaseModel()->GetParams() )
AddParam( param.info );
for( int ii = 0; ii < GetBaseModel()->GetParamCount(); ++ii )
AddParam( GetBaseModel()->GetParam( ii ).info );
}

View File

@ -66,8 +66,13 @@ std::string SPICE_GENERATOR_SWITCH::ItemParams() const
{
std::string result;
for( const SIM_MODEL::PARAM& param : GetInstanceParams() )
for( int ii = 0; ii < m_model.GetParamCount(); ++ii )
{
const SIM_MODEL::PARAM& param = m_model.GetParam( ii );
if( !param.info.isSpiceInstanceParam )
continue;
// The only instance param is "ic", which is positional.
std::string value = param.value;

View File

@ -29,6 +29,7 @@
#include <pegtl/contrib/parse_tree.hpp>
#include <fmt/core.h>
#include <math/util.h>
#include <wx/regex.h>
#define CALL_INSTANCE( ValueType, Notation, func, ... ) \
@ -370,6 +371,13 @@ std::string SIM_VALUE::ConvertNotation( const std::string& aString, NOTATION aFr
NOTATION aToNotation )
{
wxString buf( aString );
// PEGTL is slow as shit. Avoid if possible.
static const wxRegEx plainNumber( wxS( "^[0-9.]*$" ) );
if( plainNumber.Matches( buf ) )
return aString;
buf.Replace( ',', '.' );
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( buf.ToStdString(),

View File

@ -62,8 +62,10 @@ std::string SPICE_GENERATOR::ModelLine( const SPICE_ITEM& aItem ) const
result.append( "\n" );
for( const SIM_MODEL::PARAM& param : m_model.GetParams() )
for( int ii = 0; ii < m_model.GetParamCount(); ++ii )
{
const SIM_MODEL::PARAM& param = m_model.GetParam( ii );
if( param.info.isSpiceInstanceParam )
continue;
@ -181,8 +183,13 @@ std::string SPICE_GENERATOR::ItemParams() const
{
std::string result;
for( const SIM_MODEL::PARAM& param : GetInstanceParams() )
for( int ii = 0; ii < m_model.GetParamCount(); ++ii )
{
const SIM_MODEL::PARAM& param = m_model.GetParam( ii );
if( !param.info.isSpiceInstanceParam )
continue;
std::string name = param.info.spiceInstanceName.empty() ? param.info.name
: param.info.spiceInstanceName;
std::string value = SIM_VALUE::ToSpice( param.value );
@ -230,17 +237,3 @@ std::string SPICE_GENERATOR::Preview( const SPICE_ITEM& aItem ) const
}
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> SPICE_GENERATOR::GetInstanceParams() const
{
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> instanceParams;
for( const SIM_MODEL::PARAM& param : m_model.GetParams() )
{
if( param.info.isSpiceInstanceParam )
instanceParams.emplace_back( param );
}
return instanceParams;
}

View File

@ -70,8 +70,6 @@ protected:
return m_model.GetPins();
}
virtual std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> GetInstanceParams() const;
const SIM_MODEL& m_model;
};

View File

@ -292,9 +292,6 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadTypeFromSpiceStrings( const std::string&
for( SIM_MODEL::TYPE candidate : SIM_MODEL::TYPE_ITERATOR() )
{
wxString candidate_type = SIM_MODEL::SpiceInfo( candidate ).modelType;
wxString candidate_level = SIM_MODEL::SpiceInfo( candidate ).level;
wxString candidate_version = SIM_MODEL::SpiceInfo( candidate ).version;
bool candidate_isDefaultLevel = SIM_MODEL::SpiceInfo( candidate ).isDefaultLevel;
if( candidate_type.IsEmpty() )
continue;
@ -308,16 +305,16 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadTypeFromSpiceStrings( const std::string&
}
else if( input_type.StartsWith( candidate_type ) )
{
if( candidate_version != aVersion )
if( SIM_MODEL::SpiceInfo( candidate ).version != aVersion )
continue;
if( candidate_level == input_level )
if( SIM_MODEL::SpiceInfo( candidate ).level == input_level )
return candidate;
if( aSkipDefaultLevel )
continue;
if( candidate_isDefaultLevel && aLevel == "" )
if( SIM_MODEL::SpiceInfo( candidate ).isDefaultLevel && aLevel == "" )
return candidate;
}
}