Skip to content

Commit c4c899e

Browse files
authored
Faster Array Allocation (#1999)
* Allocate arrays more efficiently. * Update CHANGELOG
1 parent 4f23cd7 commit c4c899e

File tree

14 files changed

+37
-36
lines changed

14 files changed

+37
-36
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ All notable changes to this project will be documented in this file.
3737
* #### Added
3838
* #### Changed
3939
* Fix [#1970](https://github.com/ni/nimi-python/issues/1970): Incorrect error when driver runtime not installed.
40+
* Fix [#1998](https://github.com/ni/nimi-python/issues/1998): nimi-python APIs inefficiently allocate Python arrays.
4041
* #### Removed
4142
* Support for Python 3.7
4243
* ### `nidcpower` (NI-DCPower)

build/helper/codegen_helper.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,10 @@ def _get_ctype_variable_definition_snippet_for_buffers(parameter, parameters, iv
411411
B560. Output buffer with mechanism python-code: _get_ctypes_pointer_for_buffer(value=array.array('d'), library_type=ViInt32)
412412
B570. Output buffer with mechanism fixed-size: _get_ctypes_pointer_for_buffer(library_type=ViInt32, size=256)
413413
B580. Output buffer with mechanism ivi-dance, QUERY_SIZE: None
414-
B590. Output buffer with mechanism ivi-dance, GET_DATA: _get_ctypes_pointer_for_buffer(value=array.array('d', [0] * buffer_size_ctype.value, library_type=ViInt32)
415-
B600. Output buffer with mechanism passed-in: _get_ctypes_pointer_for_buffer(value-array.array('d', [0] * buffer_size, library_type=ViInt32)
414+
B590. Output buffer with mechanism ivi-dance, GET_DATA: _get_ctypes_pointer_for_buffer(value=array.array('d', [0]) * buffer_size_ctype.value, library_type=ViInt32)
415+
B600. Output buffer with mechanism passed-in: _get_ctypes_pointer_for_buffer(value-array.array('d', [0]) * buffer_size, library_type=ViInt32)
416416
B610. Output buffer with mechanism ivi-dance-with-a-twist, QUERY_SIZE: None
417-
B620. Output buffer with mechanism ivi-dance-with-a-twist, GET_DATA: _get_ctypes_pointer_for_buffer(value=array.array('d', [0] * buffer_size_ctype.value, library_type=ViInt32)
417+
B620. Output buffer with mechanism ivi-dance-with-a-twist, GET_DATA: _get_ctypes_pointer_for_buffer(value=array.array('d', [0]) * buffer_size_ctype.value, library_type=ViInt32)
418418
419419
Return Value (list): each item in the list will be one line needed for the declaration of that parameter
420420
@@ -447,7 +447,7 @@ def _get_ctype_variable_definition_snippet_for_buffers(parameter, parameters, iv
447447
line1 = '{0}_size = {1} # case B560'.format(parameter['python_name'], parameter['size']['value'])
448448
definitions.append(line1)
449449
if parameter['use_array']:
450-
line2 = '{0}_array = array.array("{1}", [0] * {0}_size) # case B560'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
450+
line2 = '{0}_array = array.array("{1}", [0]) * {0}_size # case B560'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
451451
definitions.append(line2)
452452
definition = '_get_ctypes_pointer_for_buffer(value={1}_array, library_type={0}.{2}) # case B560'.format(module_name, parameter['python_name'], parameter['ctypes_type'])
453453
elif parameter['use_list']:
@@ -459,7 +459,7 @@ def _get_ctype_variable_definition_snippet_for_buffers(parameter, parameters, iv
459459
line1 = '{0}_size = {1} # case B570'.format(parameter['python_name'], parameter['size']['value'])
460460
definitions.append(line1)
461461
if parameter['use_array']:
462-
line2 = '{0}_array = array.array("{1}", [0] * {0}_size) # case B570'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
462+
line2 = '{0}_array = array.array("{1}", [0]) * {0}_size # case B570'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
463463
definitions.append(line2)
464464
definition = '_get_ctypes_pointer_for_buffer(value={1}_array, library_type={0}.{2}) # case B570'.format(module_name, parameter['python_name'], parameter['ctypes_type'])
465465
elif parameter['use_list']:
@@ -474,7 +474,7 @@ def _get_ctype_variable_definition_snippet_for_buffers(parameter, parameters, iv
474474
line1 = '{0}_size = {1}.value # case B590'.format(parameter['python_name'], size_parameter['ctypes_variable_name'])
475475
definitions.append(line1)
476476
if parameter['use_array']:
477-
line2 = '{0}_array = array.array("{1}", [0] * {0}_size) # case B590'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
477+
line2 = '{0}_array = array.array("{1}", [0]) * {0}_size # case B590'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
478478
definition = '_get_ctypes_pointer_for_buffer(value={1}_array, library_type={0}.{2}) # case B590'.format(module_name, parameter['python_name'], parameter['ctypes_type'])
479479
definitions.append(line2)
480480
elif parameter['use_list']:
@@ -491,7 +491,7 @@ def _get_ctype_variable_definition_snippet_for_buffers(parameter, parameters, iv
491491
line1 = '{0}_size = {1}.value # case B620'.format(parameter['python_name'], size_parameter_twist['ctypes_variable_name'])
492492
definitions.append(line1)
493493
if parameter['use_array']:
494-
line2 = '{0}_array = array.array("{1}", [0] * {0}_size) # case B620'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
494+
line2 = '{0}_array = array.array("{1}", [0]) * {0}_size # case B620'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
495495
definitions.append(line2)
496496
definition = '_get_ctypes_pointer_for_buffer(value={1}_array, library_type={0}.{2}) # case B620'.format(module_name, parameter['python_name'], parameter['ctypes_type'])
497497
elif parameter['use_list']:
@@ -505,7 +505,7 @@ def _get_ctype_variable_definition_snippet_for_buffers(parameter, parameters, iv
505505
line1 = '{0}_size = {1} # case B600'.format(parameter['python_name'], size_parameter['python_name'])
506506
definitions.append(line1)
507507
if parameter['use_array']:
508-
line2 = '{0}_array = array.array("{1}", [0] * {0}_size) # case B600'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
508+
line2 = '{0}_array = array.array("{1}", [0]) * {0}_size # case B600'.format(parameter['python_name'], get_array_type_for_api_type(parameter['ctypes_type']))
509509
definition = '_get_ctypes_pointer_for_buffer(value={1}_array, library_type={0}.{2}) # case B600'.format(module_name, parameter['python_name'], parameter['ctypes_type'])
510510
definitions.append(line2)
511511
elif parameter['use_list']:

build/unit_tests/test_codegen_helper.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ def test_get_ctype_variable_declaration_snippet_case_b570():
12201220
actual = get_ctype_variable_declaration_snippet(parameters_for_testing[18], parameters_for_testing, IviDanceStep.NOT_APPLICABLE, config_for_testing, use_numpy_array=False)
12211221
expected = [
12221222
'an_int_size = 256 # case B570',
1223-
'an_int_array = array.array("h", [0] * an_int_size) # case B570',
1223+
'an_int_array = array.array("h", [0]) * an_int_size # case B570',
12241224
'an_int_ctype = _get_ctypes_pointer_for_buffer(value=an_int_array, library_type=_visatype.ViInt16) # case B570',
12251225
]
12261226
assert len(actual) == len(expected)
@@ -1237,7 +1237,7 @@ def test_get_ctype_variable_declaration_snippet_case_b590_array():
12371237
actual = get_ctype_variable_declaration_snippet(parameters_for_testing[24], parameters_for_testing, IviDanceStep.GET_DATA, config_for_testing, use_numpy_array=False)
12381238
expected = [
12391239
'a_buffer_array_size = string_size_ctype.value # case B590',
1240-
'a_buffer_array_array = array.array("l", [0] * a_buffer_array_size) # case B590',
1240+
'a_buffer_array_array = array.array("l", [0]) * a_buffer_array_size # case B590',
12411241
'a_buffer_array_ctype = _get_ctypes_pointer_for_buffer(value=a_buffer_array_array, library_type=_visatype.ViInt32) # case B590',
12421242
]
12431243
assert len(actual) == len(expected)
@@ -1265,7 +1265,7 @@ def test_get_ctype_variable_declaration_snippet_case_b600():
12651265
actual = get_ctype_variable_declaration_snippet(parameters_for_testing[7], parameters_for_testing, IviDanceStep.NOT_APPLICABLE, config_for_testing, use_numpy_array=False)
12661266
expected = [
12671267
'output_size = number_of_elements # case B600',
1268-
'output_array = array.array("q", [0] * output_size) # case B600',
1268+
'output_array = array.array("q", [0]) * output_size # case B600',
12691269
'output_ctype = _get_ctypes_pointer_for_buffer(value=output_array, library_type=_visatype.ViInt64) # case B600',
12701270
]
12711271
assert len(actual) == len(expected)
@@ -1282,7 +1282,7 @@ def test_get_ctype_variable_declaration_snippet_case_b620_array():
12821282
actual = get_ctype_variable_declaration_snippet(parameters_for_testing[26], parameters_for_testing, IviDanceStep.GET_DATA, config_for_testing, use_numpy_array=False)
12831283
expected = [
12841284
'a_buffer_twist_array_size = output_twist_ctype.value # case B620',
1285-
'a_buffer_twist_array_array = array.array("l", [0] * a_buffer_twist_array_size) # case B620',
1285+
'a_buffer_twist_array_array = array.array("l", [0]) * a_buffer_twist_array_size # case B620',
12861286
'a_buffer_twist_array_ctype = _get_ctypes_pointer_for_buffer(value=a_buffer_twist_array_array, library_type=_visatype.ViInt32) # case B620',
12871287
]
12881288
assert len(actual) == len(expected)

generated/nidcpower/nidcpower/_library_interpreter.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ def export_attribute_configuration_buffer(self): # noqa: N802
220220
errors.handle_error(self, error_code, ignore_warnings=True, is_error_handling=False)
221221
size_ctype = _visatype.ViInt32(error_code) # case S180
222222
configuration_size = size_ctype.value # case B590
223-
configuration_array = array.array("b", [0] * configuration_size) # case B590
223+
configuration_array = array.array("b", [0]) * configuration_size # case B590
224224
configuration_ctype = _get_ctypes_pointer_for_buffer(value=configuration_array, library_type=_visatype.ViInt8) # case B590
225225
error_code = self._library.niDCPower_ExportAttributeConfigurationBuffer(vi_ctype, size_ctype, configuration_ctype)
226226
errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False)
@@ -250,10 +250,10 @@ def fetch_multiple(self, channel_name, timeout, count): # noqa: N802
250250
timeout_ctype = _visatype.ViReal64(timeout) # case S150
251251
count_ctype = _visatype.ViInt32(count) # case S210
252252
voltage_measurements_size = count # case B600
253-
voltage_measurements_array = array.array("d", [0] * voltage_measurements_size) # case B600
253+
voltage_measurements_array = array.array("d", [0]) * voltage_measurements_size # case B600
254254
voltage_measurements_ctype = _get_ctypes_pointer_for_buffer(value=voltage_measurements_array, library_type=_visatype.ViReal64) # case B600
255255
current_measurements_size = count # case B600
256-
current_measurements_array = array.array("d", [0] * current_measurements_size) # case B600
256+
current_measurements_array = array.array("d", [0]) * current_measurements_size # case B600
257257
current_measurements_ctype = _get_ctypes_pointer_for_buffer(value=current_measurements_array, library_type=_visatype.ViReal64) # case B600
258258
in_compliance_size = count # case B600
259259
in_compliance_ctype = _get_ctypes_pointer_for_buffer(library_type=_visatype.ViBoolean, size=in_compliance_size) # case B600
@@ -397,7 +397,7 @@ def get_lcr_compensation_data(self, channel_name): # noqa: N802
397397
errors.handle_error(self, error_code, ignore_warnings=True, is_error_handling=False)
398398
compensation_data_size_ctype = _visatype.ViInt32(error_code) # case S180
399399
compensation_data_size = compensation_data_size_ctype.value # case B590
400-
compensation_data_array = array.array("b", [0] * compensation_data_size) # case B590
400+
compensation_data_array = array.array("b", [0]) * compensation_data_size # case B590
401401
compensation_data_ctype = _get_ctypes_pointer_for_buffer(value=compensation_data_array, library_type=_visatype.ViInt8) # case B590
402402
error_code = self._library.niDCPower_GetLCRCompensationData(vi_ctype, channel_name_ctype, compensation_data_size_ctype, compensation_data_ctype)
403403
errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False)
@@ -425,7 +425,7 @@ def get_lcr_custom_cable_compensation_data(self, channel_name): # noqa: N802
425425
errors.handle_error(self, error_code, ignore_warnings=True, is_error_handling=False)
426426
custom_cable_compensation_data_size_ctype = _visatype.ViInt32(error_code) # case S180
427427
custom_cable_compensation_data_size = custom_cable_compensation_data_size_ctype.value # case B590
428-
custom_cable_compensation_data_array = array.array("b", [0] * custom_cable_compensation_data_size) # case B590
428+
custom_cable_compensation_data_array = array.array("b", [0]) * custom_cable_compensation_data_size # case B590
429429
custom_cable_compensation_data_ctype = _get_ctypes_pointer_for_buffer(value=custom_cable_compensation_data_array, library_type=_visatype.ViInt8) # case B590
430430
error_code = self._library.niDCPower_GetLCRCustomCableCompensationData(vi_ctype, channel_name_ctype, custom_cable_compensation_data_size_ctype, custom_cable_compensation_data_ctype)
431431
errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False)
@@ -511,10 +511,10 @@ def measure_multiple(self, channel_name): # noqa: N802
511511
vi_ctype = _visatype.ViSession(self._vi) # case S110
512512
channel_name_ctype = ctypes.create_string_buffer(channel_name.encode(self._encoding)) # case C010
513513
voltage_measurements_size = self.parse_channel_count(channel_name) # case B560
514-
voltage_measurements_array = array.array("d", [0] * voltage_measurements_size) # case B560
514+
voltage_measurements_array = array.array("d", [0]) * voltage_measurements_size # case B560
515515
voltage_measurements_ctype = _get_ctypes_pointer_for_buffer(value=voltage_measurements_array, library_type=_visatype.ViReal64) # case B560
516516
current_measurements_size = self.parse_channel_count(channel_name) # case B560
517-
current_measurements_array = array.array("d", [0] * current_measurements_size) # case B560
517+
current_measurements_array = array.array("d", [0]) * current_measurements_size # case B560
518518
current_measurements_ctype = _get_ctypes_pointer_for_buffer(value=current_measurements_array, library_type=_visatype.ViReal64) # case B560
519519
error_code = self._library.niDCPower_MeasureMultiple(vi_ctype, channel_name_ctype, voltage_measurements_ctype, current_measurements_ctype)
520520
errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False)

generated/nidigital/nidigital/_library_interpreter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ def fetch_capture_waveform(self, site_list, waveform_name, samples_to_read, time
392392
errors.handle_error(self, error_code, ignore_warnings=True, is_error_handling=False)
393393
data_buffer_size_ctype = _visatype.ViInt32(actual_num_waveforms_ctype.value * actual_samples_per_waveform_ctype.value) # case S200 (modified)
394394
data_size = actual_num_waveforms_ctype.value * actual_samples_per_waveform_ctype.value # case B620 (modified)
395-
data_array = array.array("L", [0] * data_size) # case B620
395+
data_array = array.array("L", [0]) * data_size # case B620
396396
data_ctype = _get_ctypes_pointer_for_buffer(value=data_array, library_type=_visatype.ViUInt32) # case B620
397397
error_code = self._library.niDigital_FetchCaptureWaveformU32(vi_ctype, site_list_ctype, waveform_name_ctype, samples_to_read_ctype, timeout_ctype, data_buffer_size_ctype, data_ctype, None if actual_num_waveforms_ctype is None else (ctypes.pointer(actual_num_waveforms_ctype)), None if actual_samples_per_waveform_ctype is None else (ctypes.pointer(actual_samples_per_waveform_ctype)))
398398
errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False)

generated/nidigital/nidigital/session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3523,7 +3523,7 @@ def write_source_waveform_site_unique(self, waveform_name, waveform_data):
35233523
actual_samples_per_waveform = 0
35243524
else:
35253525
actual_samples_per_waveform = len(waveform_data[next(iter(waveform_data))])
3526-
data = array.array('L', [0] * (len(waveform_data) * actual_samples_per_waveform))
3526+
data = array.array('L', [0]) * (len(waveform_data) * actual_samples_per_waveform)
35273527
mv = memoryview(data)
35283528

35293529
i = 0

0 commit comments

Comments
 (0)