Каков рекомендуемый способ выделения памяти для типизированного представления памяти?
Документация Cython по типизированным представлениям памяти перечислите три способа назначения типизированной памяти:
из необработанного указателя C,изnp.ndarray
а такжеизcython.view.array
.Предположим, что у меня нет данных, переданных в мою функцию Cython извне, но вместо этого я хочу выделить память и вернуть ее какnp.ndarray
Какой из этих вариантов я выбрал? Также предположим, что размер этого буфера не является константой времени компиляции, т.е. я не могу выделить в стеке, но нужноmalloc
для варианта 1.
Таким образом, 3 варианта будут выглядеть примерно так:
from libc.stdlib cimport malloc, free
cimport numpy as np
from cython cimport view
np.import_array()
def memview_malloc(int N):
cdef int * m = <int *>malloc(N * sizeof(int))
cdef int[::1] b = <int[:N]>m
free(<void *>m)
def memview_ndarray(int N):
cdef int[::1] b = np.empty(N, dtype=np.int32)
def memview_cyarray(int N):
cdef int[::1] b = view.array(shape=(N,), itemsize=sizeof(int), format="i")
Что меня удивляет, так это то, что во всех трех случаяхCython генерирует довольно много кода для выделения памяти, в частности, вызов__Pyx_PyObject_to_MemoryviewSlice_dc_int
, Это говорит о том (и я могу ошибаться, мое понимание внутренней работы Cython очень ограничено), что он сначала создает объект Python, а затем «встраивает» его в представление памяти, что кажется ненужным.
A простой тест не показывает большой разницы между этими тремя методами, причем 2. является самым быстрым с небольшим отрывом.
Какой из трех методов рекомендуется? Или есть другой, лучший вариант?
Дополнительный вопрос: Я хочу, наконец, вернуть результат в видеnp.ndarray
после работы с этим видом памяти в функции. Является ли типизированное представление памяти лучшим выбором или я бы просто использовал старый интерфейс буфера, как показано ниже, для созданияndarray
на первом месте?
cdef np.ndarray[DTYPE_t, ndim=1] b = np.empty(N, dtype=np.int32)