Чтобы добиться этого, вы должны получить прямой доступ к C-API numpy, который, по крайней мере, частично упакован Cython. В вашем случае вам нужно PyArray_SimpleNew
, что уже связано с numpy .
Таким образом, ваша функция становится:
%%cython
cimport numpy as cnp
cnp.import_array() # needed to initialize numpy-API
cpdef return_empty():
cdef cnp.npy_intp dim = 0
return cnp.PyArray_SimpleNew(1, &dim, cnp.NPY_INT32)
А сейчас:
>>> return_empty()
array([], dtype=int32)
Очевидно, что из-за подсчета ссылок все еще есть некоторые издержки Python, но они намного меньше, чем при использовании np.empty()
:
>>> %timeit return_empty()
159 ns ± 2.81 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
>>> %timeit return_empty_py
751 ns ± 8.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Использование PyArray_SimpleNew
также быстрее (примерно в 3 раза), чем использование array
в Cython (как вы считаете в другом вопросе ):
%%cython
from cython.view cimport array as cvarray
# shape=(0,) doesn't work
cpdef create_almost_empty_carray():
return cvarray(shape=(1,), itemsize=sizeof(int), format="i")
и, таким образом:
>>> %timeit create_almost_empty_carray()
435 ns ± 5.85 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Список использованных функций return_empty_py
:
%%cython
cimport numpy as cnp
import numpy as np
cpdef return_empty_py():
return np.empty(0, np.int32)