Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit 6f15c98

Browse files
authored
perf: reduce cppcore initialisation (#410)
1 parent e9bcd51 commit 6f15c98

File tree

7 files changed

+64
-20
lines changed

7 files changed

+64
-20
lines changed

CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
66
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
77

8+
5.7.9 - 2024-09
9+
---------------
10+
11+
- Reduces redundant dependency tree initializations in cppcore, improving feature extraction performance by up to 2.5x. Ensures getFeatureValues avoids unnecessary resets; use efel.reset to reload dependencies when needed.
12+
813
5.6.7 - 2024-08
914
---------------
1015

efel/api.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,11 @@ def _initialise() -> None:
212212
cppcore.Initialize(_settings.dependencyfile_path, "log")
213213
# flush the GErrorString from previous runs by calling getgError()
214214
cppcore.getgError()
215+
_initSettings()
215216

216-
# Set the settings in the cppcore
217+
218+
def _initSettings() -> None:
219+
"""Init the settings in cppcore."""
217220
settings_attrs = vars(_settings)
218221
for setting_name, setting_value in settings_attrs.items():
219222
if isinstance(setting_value, bool):
@@ -356,7 +359,8 @@ def _get_feature_values_serial(
356359
else:
357360
raise Exception('stim_start or stim_end missing from trace')
358361

359-
_initialise()
362+
cppcore.Clear()
363+
_initSettings()
360364

361365
# Next set time, voltage and the stimulus start and end
362366
for item in list(trace.keys()):

efel/cppcore.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
def Initialize(depfilename: str, outfilename: str) -> int: ...
2+
def Clear() -> int: ...
23
def getFeature(feature_name: str, values: list) -> int: ...
34
def getFeatureInt(feature_name: str, values: list[int]) -> int: ...
45
def getFeatureDouble(feature_name: str, values: list[float]) -> int: ...

efel/cppcore/cfeature.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ cFeature::cFeature(const string& strDepFile, const string& outdir)
5454
logger << "Using dependency file: " << strDepFile << endl;
5555
}
5656

57+
void cFeature::clearMap()
58+
{
59+
mapIntData.clear();
60+
mapDoubleData.clear();
61+
mapStrData.clear();
62+
}
63+
5764
template <typename T>
5865
const vector<T> cFeature::getMapData(const string& strName,
5966
const map<string, vector<T>>& mapData) {

efel/cppcore/cfeature.h

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
/* Copyright (c) 2015, EPFL/Blue Brain Project
2-
*
3-
* This file is part of eFEL <https://github.com/BlueBrain/eFEL>
4-
*
5-
* This library is free software; you can redistribute it and/or modify it under
6-
* the terms of the GNU Lesser General Public License version 3.0 as published
7-
* by the Free Software Foundation.
8-
*
9-
* This library is distributed in the hope that it will be useful, but WITHOUT
10-
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11-
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12-
* details.
13-
*
14-
* You should have received a copy of the GNU Lesser General Public License
15-
* along with this library; if not, write to the Free Software Foundation, Inc.,
16-
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1+
/* Copyright (c) 2015, EPFL/Blue Brain Project
2+
*
3+
* This file is part of eFEL <https://github.com/BlueBrain/eFEL>
4+
*
5+
* This library is free software; you can redistribute it and/or modify it under
6+
* the terms of the GNU Lesser General Public License version 3.0 as published
7+
* by the Free Software Foundation.
8+
*
9+
* This library is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11+
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12+
* details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with this library; if not, write to the Free Software Foundation, Inc.,
16+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1717
*/
18-
18+
1919
#ifndef CFEATURE_H_
2020
#define CFEATURE_H_
2121

@@ -62,6 +62,7 @@ class cFeature {
6262
string featuretype(string featurename);
6363
string getGError();
6464
void get_feature_names(vector<string>& feature_names);
65+
void clearMap();
6566

6667
};
6768

efel/cppcore/cppcore.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ int Initialize(const char* strDepFile, const char* outdir) {
5454
}
5555
}
5656

57+
void Clear() {
58+
if (pFeature != NULL) {
59+
pFeature->clearMap();
60+
}
61+
}
62+
5763
static PyObject* CppCoreInitialize(PyObject* self, PyObject* args) {
5864
char *depfilename, *outfilename;
5965
if (!PyArg_ParseTuple(args, "ss", &depfilename, &outfilename)) {
@@ -64,6 +70,11 @@ static PyObject* CppCoreInitialize(PyObject* self, PyObject* args) {
6470
return Py_BuildValue("");
6571
}
6672

73+
static PyObject* CppCoreClear(PyObject* self, PyObject* args) {
74+
Clear();
75+
return Py_BuildValue("");
76+
}
77+
6778
static vector<int> PyList_to_vectorint(PyObject* input) {
6879
vector<int> result_vector;
6980
int list_size;
@@ -293,7 +304,7 @@ static PyObject* getgerrorstr(PyObject* self, PyObject* args) {
293304

294305
static PyMethodDef CppCoreMethods[] = {
295306
{"Initialize", CppCoreInitialize, METH_VARARGS, "Initialise CppCore."},
296-
307+
{"Clear", CppCoreClear, METH_NOARGS, "Clear CppCore."},
297308
{"getFeature", getfeature, METH_VARARGS,
298309
"Get a values associated with a feature. Takes a list() to be filled."},
299310
{"getFeatureInt", getfeatureint, METH_VARARGS, "Get a integer feature."},

tests/test_cppcore.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,21 @@ def test_caching(self, feature_name):
258258
# make sure Reusing computed value of text occurs twice
259259
assert contents.count(f"Reusing computed value of {feature_name}") == 2
260260

261+
def test_clear_function(self):
262+
"""cppcore: Testing Clear function to reset state"""
263+
import efel
264+
self.setup_data()
265+
266+
feature_values = list()
267+
efel.cppcore.getFeature('AP_amplitude', feature_values)
268+
assert len(feature_values) > 0 # Data should be present
269+
270+
efel.cppcore.Clear()
271+
272+
feature_values = list()
273+
return_value = efel.cppcore.getFeature('AP_amplitude', feature_values)
274+
assert return_value == -1 # Should return -1 since data is cleared
275+
261276

262277
def test_efel_assertion_error():
263278
"""Testing if C++ assertion error is propagated to Python correctly."""

0 commit comments

Comments
 (0)