Skip to content

Commit 63332fc

Browse files
committed
Improvements to the overall speed and memory use of libCellML.
1 parent 8cfa98e commit 63332fc

50 files changed

Lines changed: 1340 additions & 999 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎src/analyser.cpp‎

Lines changed: 165 additions & 98 deletions
Large diffs are not rendered by default.

‎src/analyser_p.h‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
#include "libcellml/generatorprofile.h"
1818
#include "libcellml/issue.h"
1919

20+
#include <unordered_set>
21+
2022
#include "analysermodel_p.h"
2123
#include "internaltypes.h"
2224
#include "logger_p.h"
@@ -96,9 +98,12 @@ struct AnalyserInternalEquation
9698
ComponentPtr mComponent;
9799

98100
AnalyserInternalVariablePtrs mVariables;
101+
std::unordered_set<AnalyserInternalVariable *> mVariablesSet;
99102
AnalyserInternalVariablePtrs mStateVariables;
103+
std::unordered_set<AnalyserInternalVariable *> mStateVariablesSet;
100104
AnalyserInternalVariablePtrs mAllVariables;
101105
AnalyserInternalVariablePtrs mUnknownVariables;
106+
std::unordered_set<AnalyserInternalVariable *> mUnknownVariablesSet;
102107

103108
size_t mNlaSystemIndex = MAX_SIZE_T;
104109
AnalyserInternalEquationWeakPtrs mNlaSiblings;
@@ -160,12 +165,13 @@ class Analyser::AnalyserImpl: public Logger::LoggerImpl
160165
AnalyserExternalVariablePtrs mExternalVariables;
161166

162167
AnalyserInternalVariablePtrs mInternalVariables;
168+
std::unordered_map<Variable *, AnalyserInternalVariablePtr> mInternalVariableCache;
163169
AnalyserInternalEquationPtrs mInternalEquations;
164170

165171
GeneratorProfilePtr mGeneratorProfile = GeneratorProfile::create();
166172

167-
std::map<std::string, UnitsPtr> mStandardUnits;
168-
std::map<AnalyserEquationAstPtr, UnitsPtr> mCiCnUnits;
173+
std::unordered_map<std::string, UnitsPtr> mStandardUnits;
174+
std::unordered_map<AnalyserEquationAstPtr, UnitsPtr> mCiCnUnits;
169175

170176
AnalyserImpl();
171177

@@ -181,8 +187,8 @@ class Analyser::AnalyserImpl: public Logger::LoggerImpl
181187
void analyseComponent(const ComponentPtr &component);
182188
void analyseComponentVariables(const ComponentPtr &component);
183189

184-
void equivalentVariables(const VariablePtr &variable,
185-
VariablePtrs &equivalentVariables) const;
190+
void equivalentVariables(const VariablePtr &variable, VariablePtrs &equivalentVariables,
191+
std::unordered_set<Variable *> &seen) const;
186192
VariablePtrs equivalentVariables(const VariablePtr &variable) const;
187193

188194
void analyseEquationAst(const AnalyserEquationAstPtr &ast);
@@ -251,7 +257,7 @@ class Analyser::AnalyserImpl: public Logger::LoggerImpl
251257
static bool isExternalVariable(const AnalyserInternalVariablePtr &variable);
252258

253259
bool isStateRateBased(const AnalyserEquationPtr &analyserEquation,
254-
AnalyserEquationPtrs &checkedEquations);
260+
std::unordered_set<AnalyserEquation *> &checkedEquations);
255261

256262
void addInvalidVariableIssue(const AnalyserInternalVariablePtr &variable,
257263
Issue::ReferenceRule referenceRule);

‎src/analyserequation.cpp‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ std::vector<AnalyserEquationPtr> AnalyserEquation::dependencies() const
9393
{
9494
std::vector<AnalyserEquationPtr> res;
9595

96+
res.reserve(mPimpl->mDependencies.size());
97+
9698
for (const auto &dependency : mPimpl->mDependencies) {
9799
res.push_back(dependency.lock());
98100
}
@@ -123,6 +125,8 @@ std::vector<AnalyserEquationPtr> AnalyserEquation::nlaSiblings() const
123125
{
124126
std::vector<AnalyserEquationPtr> res;
125127

128+
res.reserve(mPimpl->mNlaSiblings.size());
129+
126130
for (const auto &nlaSibling : mPimpl->mNlaSiblings) {
127131
res.push_back(nlaSibling.lock());
128132
}
@@ -149,7 +153,7 @@ size_t AnalyserEquation::stateCount() const
149153
return mPimpl->mStates.size();
150154
}
151155

152-
std::vector<AnalyserVariablePtr> AnalyserEquation::states() const
156+
const std::vector<AnalyserVariablePtr> &AnalyserEquation::states() const
153157
{
154158
return mPimpl->mStates;
155159
}
@@ -168,7 +172,7 @@ size_t AnalyserEquation::computedConstantCount() const
168172
return mPimpl->mComputedConstants.size();
169173
}
170174

171-
std::vector<AnalyserVariablePtr> AnalyserEquation::computedConstants() const
175+
const std::vector<AnalyserVariablePtr> &AnalyserEquation::computedConstants() const
172176
{
173177
return mPimpl->mComputedConstants;
174178
}
@@ -187,7 +191,7 @@ size_t AnalyserEquation::algebraicVariableCount() const
187191
return mPimpl->mAlgebraicVariables.size();
188192
}
189193

190-
std::vector<AnalyserVariablePtr> AnalyserEquation::algebraicVariables() const
194+
const std::vector<AnalyserVariablePtr> &AnalyserEquation::algebraicVariables() const
191195
{
192196
return mPimpl->mAlgebraicVariables;
193197
}
@@ -206,7 +210,7 @@ size_t AnalyserEquation::externalVariableCount() const
206210
return mPimpl->mExternalVariables.size();
207211
}
208212

209-
std::vector<AnalyserVariablePtr> AnalyserEquation::externalVariables() const
213+
const std::vector<AnalyserVariablePtr> &AnalyserEquation::externalVariables() const
210214
{
211215
return mPimpl->mExternalVariables;
212216
}

‎src/analyserequationast.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ void AnalyserEquationAst::setType(Type type)
170170
mPimpl->mType = type;
171171
}
172172

173-
std::string AnalyserEquationAst::value() const
173+
const std::string &AnalyserEquationAst::value() const
174174
{
175175
return mPimpl->mValue;
176176
}

‎src/analyserexternalvariable.cpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ std::vector<VariablePtr>::iterator AnalyserExternalVariable::AnalyserExternalVar
3131
const std::string &componentName,
3232
const std::string &variableName)
3333
{
34-
return std::find_if(mDependencies.begin(), mDependencies.end(), [=](const auto &v) {
34+
return std::find_if(mDependencies.begin(), mDependencies.end(), [&](const auto &v) {
3535
return (owningModel(v) == model)
3636
&& (owningComponent(v)->name() == componentName)
3737
&& (v->name() == variableName);
@@ -40,7 +40,7 @@ std::vector<VariablePtr>::iterator AnalyserExternalVariable::AnalyserExternalVar
4040

4141
std::vector<VariablePtr>::iterator AnalyserExternalVariable::AnalyserExternalVariableImpl::findDependency(const VariablePtr &variable)
4242
{
43-
return std::find_if(mDependencies.begin(), mDependencies.end(), [=](const auto &v) {
43+
return std::find_if(mDependencies.begin(), mDependencies.end(), [&](const auto &v) {
4444
return v == variable;
4545
});
4646
}
@@ -155,7 +155,7 @@ VariablePtr AnalyserExternalVariable::dependency(const ModelPtr &model,
155155
nullptr;
156156
}
157157

158-
std::vector<VariablePtr> AnalyserExternalVariable::dependencies() const
158+
const std::vector<VariablePtr> &AnalyserExternalVariable::dependencies() const
159159
{
160160
return mPimpl->mDependencies;
161161
}

‎src/analysermodel.cpp‎

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,12 @@ size_t AnalyserModel::stateCount() const
104104
return mPimpl->mStates.size();
105105
}
106106

107-
std::vector<AnalyserVariablePtr> AnalyserModel::states() const
107+
const std::vector<AnalyserVariablePtr> &AnalyserModel::states() const
108108
{
109+
static const std::vector<AnalyserVariablePtr> empty;
110+
109111
if (!isValid()) {
110-
return {};
112+
return empty;
111113
}
112114

113115
return mPimpl->mStates;
@@ -132,10 +134,12 @@ size_t AnalyserModel::constantCount() const
132134
return mPimpl->mConstants.size();
133135
}
134136

135-
std::vector<AnalyserVariablePtr> AnalyserModel::constants() const
137+
const std::vector<AnalyserVariablePtr> &AnalyserModel::constants() const
136138
{
139+
static const std::vector<AnalyserVariablePtr> empty;
140+
137141
if (!isValid()) {
138-
return {};
142+
return empty;
139143
}
140144

141145
return mPimpl->mConstants;
@@ -159,10 +163,12 @@ size_t AnalyserModel::computedConstantCount() const
159163
return mPimpl->mComputedConstants.size();
160164
}
161165

162-
std::vector<AnalyserVariablePtr> AnalyserModel::computedConstants() const
166+
const std::vector<AnalyserVariablePtr> &AnalyserModel::computedConstants() const
163167
{
168+
static const std::vector<AnalyserVariablePtr> empty;
169+
164170
if (!isValid()) {
165-
return {};
171+
return empty;
166172
}
167173

168174
return mPimpl->mComputedConstants;
@@ -186,10 +192,12 @@ size_t AnalyserModel::algebraicVariableCount() const
186192
return mPimpl->mAlgebraicVariables.size();
187193
}
188194

189-
std::vector<AnalyserVariablePtr> AnalyserModel::algebraicVariables() const
195+
const std::vector<AnalyserVariablePtr> &AnalyserModel::algebraicVariables() const
190196
{
197+
static const std::vector<AnalyserVariablePtr> empty;
198+
191199
if (!isValid()) {
192-
return {};
200+
return empty;
193201
}
194202

195203
return mPimpl->mAlgebraicVariables;
@@ -213,10 +221,12 @@ size_t AnalyserModel::externalVariableCount() const
213221
return mPimpl->mExternalVariables.size();
214222
}
215223

216-
std::vector<AnalyserVariablePtr> AnalyserModel::externalVariables() const
224+
const std::vector<AnalyserVariablePtr> &AnalyserModel::externalVariables() const
217225
{
226+
static const std::vector<AnalyserVariablePtr> empty;
227+
218228
if (!isValid()) {
219-
return {};
229+
return empty;
220230
}
221231

222232
return mPimpl->mExternalVariables;
@@ -237,8 +247,20 @@ AnalyserVariablePtr AnalyserModel::analyserVariable(const VariablePtr &variable)
237247
return {};
238248
}
239249

250+
// Check the cache first.
251+
252+
auto analyserVariableIt = mPimpl->mAnalyserVariables.find(variable.get());
253+
254+
if (analyserVariableIt != mPimpl->mAnalyserVariables.end()) {
255+
return analyserVariableIt->second;
256+
}
257+
258+
// Not in the cache, so do the equivalence-based search.
259+
240260
for (const auto &analyserVariable : analyserVariables(shared_from_this())) {
241261
if (areEquivalentVariables(variable, analyserVariable->variable())) {
262+
mPimpl->mAnalyserVariables.emplace(variable.get(), analyserVariable);
263+
242264
return analyserVariable;
243265
}
244266
}
@@ -255,10 +277,12 @@ size_t AnalyserModel::analyserEquationCount() const
255277
return mPimpl->mAnalyserEquations.size();
256278
}
257279

258-
std::vector<AnalyserEquationPtr> AnalyserModel::analyserEquations() const
280+
const std::vector<AnalyserEquationPtr> &AnalyserModel::analyserEquations() const
259281
{
282+
static const std::vector<AnalyserEquationPtr> empty;
283+
260284
if (!isValid()) {
261-
return {};
285+
return empty;
262286
}
263287

264288
return mPimpl->mAnalyserEquations;

‎src/analysermodel_p.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ struct AnalyserModel::AnalyserModelImpl
6666
}
6767
};
6868

69+
mutable std::unordered_map<Variable *, AnalyserVariablePtr> mAnalyserVariables;
70+
6971
struct VariableKeyPairHash
7072
{
7173
size_t operator()(const VariableKeyPair &pair) const

‎src/analyservariable.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ std::vector<AnalyserEquationPtr> AnalyserVariable::analyserEquations() const
120120

121121
std::vector<AnalyserEquationPtr> res;
122122

123+
res.reserve(mPimpl->mAnalyserEquations.size());
124+
123125
for (const auto &analyserEquation : mPimpl->mAnalyserEquations) {
124126
res.push_back(analyserEquation.lock());
125127
}

‎src/annotator.cpp‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,16 @@ void Annotator::AnnotatorImpl::listComponentIdsAndItems(const ComponentPtr &comp
236236
if (idList.count(id) != 0) {
237237
// Get the range of items with this identifier:
238238
auto rangePair = idList.equal_range(id);
239+
auto compEquiv = owningComponent(equivalentVariable);
240+
auto compVar = owningComponent(variable);
239241
for (auto it = rangePair.first; it != rangePair.second; ++it) {
240242
// Make sure it's also a CONNECTION item.
241243
if (it->second->type() == CellmlElementType::CONNECTION) {
242244
auto testPair = it->second->variablePair();
243-
if ((owningComponent(testPair->variable1()) == owningComponent(equivalentVariable)) && (owningComponent(testPair->variable2()) == owningComponent(variable))) {
244-
found = true;
245-
} else if ((owningComponent(testPair->variable2()) == owningComponent(equivalentVariable)) && (owningComponent(testPair->variable1()) == owningComponent(variable))) {
245+
auto compTest1 = owningComponent(testPair->variable1());
246+
auto compTest2 = owningComponent(testPair->variable2());
247+
if ((compTest1 == compEquiv && compTest2 == compVar)
248+
|| (compTest2 == compEquiv && compTest1 == compVar)) {
246249
found = true;
247250
}
248251
}
@@ -352,7 +355,7 @@ AnyCellmlElementPtr Annotator::AnnotatorImpl::convertToWeak(const AnyCellmlEleme
352355

353356
converted->mPimpl->mType = type;
354357

355-
switch (item->type()) {
358+
switch (type) {
356359
case CellmlElementType::COMPONENT:
357360
case CellmlElementType::COMPONENT_REF: {
358361
ComponentWeakPtr weakComponent = item->component();

‎src/api/libcellml/analyserequation.h‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class LIBCELLML_EXPORT AnalyserEquation
185185
*
186186
* @return The states as a @c std::vector.
187187
*/
188-
std::vector<AnalyserVariablePtr> states() const;
188+
const std::vector<AnalyserVariablePtr> &states() const;
189189

190190
/**
191191
* @brief Get the state, at @p index, computed by this @ref AnalyserEquation.
@@ -214,7 +214,7 @@ class LIBCELLML_EXPORT AnalyserEquation
214214
*
215215
* @return The computed constants as a @c std::vector.
216216
*/
217-
std::vector<AnalyserVariablePtr> computedConstants() const;
217+
const std::vector<AnalyserVariablePtr> &computedConstants() const;
218218

219219
/**
220220
* @brief Get the computed constant, at @p index, computed by this @ref AnalyserEquation.
@@ -243,7 +243,7 @@ class LIBCELLML_EXPORT AnalyserEquation
243243
*
244244
* @return The algebraic variables as a @c std::vector.
245245
*/
246-
std::vector<AnalyserVariablePtr> algebraicVariables() const;
246+
const std::vector<AnalyserVariablePtr> &algebraicVariables() const;
247247

248248
/**
249249
* @brief Get the algebraic variable, at @p index, computed by this @ref AnalyserEquation.
@@ -272,7 +272,7 @@ class LIBCELLML_EXPORT AnalyserEquation
272272
*
273273
* @return The external variables as a @c std::vector.
274274
*/
275-
std::vector<AnalyserVariablePtr> externalVariables() const;
275+
const std::vector<AnalyserVariablePtr> &externalVariables() const;
276276

277277
/**
278278
* @brief Get the external variable, at @p index, computed by this @ref AnalyserEquation.

0 commit comments

Comments
 (0)