Passing numpy arrays efficiently
Take a look at the file mlarray_sequence.py
in the folder PYTHONPATHLibsite-packagesmatlab\_internal
. There you will find the construction of the MATLAB array object. The performance problem comes from copying data with loops within the generic_flattening
function.
To avoid this behavior we will edit the file a bit. This fix should work on complex and non-complex datatypes.
- Make a backup of the original file in case something goes wrong.
- Add
import numpy as np
to the other imports at the beginning of the file
In line 38 you should find:
init_dims = _get_size(initializer) # replace this with
try:
init_dims=initializer.shape
except:
init_dims = _get_size(initializer)
In line 48 you should find:
if is_complex:
complex_array = flat(self, initializer,
init_dims, typecode)
self._real = complex_array['real']
self._imag = complex_array['imag']
else:
self._data = flat(self, initializer, init_dims, typecode)
#Replace this with:
if is_complex:
try:
self._real = array.array(typecode,np.ravel(initializer, order='F').real)
self._imag = array.array(typecode,np.ravel(initializer, order='F').imag)
except:
complex_array = flat(self, initializer,init_dims, typecode)
self._real = complex_array['real']
self._imag = complex_array['imag']
else:
try:
self._data = array.array(typecode,np.ravel(initializer, order='F'))
except:
self._data = flat(self, initializer, init_dims, typecode)
Now you can pass a numpy array directly to the MATLAB array creation method.
data1 = np.random.uniform(low = 0.0, high = 30000.0, size = (1000000,))
#faster
data1m = matlab.double(data1)
#or slower method
data1m = matlab.double(data1.tolist())
data2 = np.random.uniform(low = 0.0, high = 30000.0, size = (1000000,)).astype(np.complex128)
#faster
data1m = matlab.double(data2,is_complex=True)
#or slower method
data1m = matlab.double(data2.tolist(),is_complex=True)
The performance in MATLAB array creation increases by a factor of 15 and the interface is easier to use now.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…