I'm trying to figure out whether I can speed up passing large int
and float
lists to my foreign function:
from ctypes import cdll, c_uint32, c_float, Structure, c_void_p, cast, c_size_t, POINTER
lib = cdll.LoadLibrary('whatever.dylib')
class _BNG_FFITuple(Structure):
_fields_ = [("a", c_uint32),
("b", c_uint32)]
class _BNG_FFIArray(Structure):
_fields_ = [("data", c_void_p),
("len", c_size_t)]
# Allow implicit conversions from a sequence of 32-bit unsigned
# integers.
@classmethod
def from_param(cls, seq):
return seq if isinstance(seq, cls) else cls(seq)
# Wrap sequence of values. You can specify another type besides a
# 32-bit unsigned integer.
def __init__(self, seq, data_type = c_float):
array_type = data_type * len(seq)
raw_seq = array_type(*seq)
self.data = cast(raw_seq, c_void_p)
self.len = len(seq)
# A conversion function that cleans up the result value to make it
# nicer to consume.
def _bng_void_array_to_tuple_list(array, _func, _args):
res = cast(array.data, POINTER(_BNG_FFITuple * array.len))[0]
res_list = [(i.a, i.b) for i in iter(res)]
drop_bng_array(array)
return res_list
convert_bng = lib.convert_to_bng_threaded
convert_bng.argtypes = (_BNG_FFIArray, _BNG_FFIArray)
convert_bng.restype = _BNG_FFIArray
convert_bng.errcheck = _bng_void_array_to_tuple_list
This means I can call convert_bng
with two lists, like so:
convert_bng(float_list, another_float_list)
and get a list of int tuples back. But I'm wondering whether I can send the _BNG_FFIArray
s by reference instead, and whether that will be faster (I'm obviously consuming them on the C side, but not changing their values).