Qual é a maneira recomendada de alocar memória para uma exibição de memória digitada?
oDocumentação do Cython em visualizações de memória digitadas lista três maneiras de atribuir a uma exibição de memória digitada:
de um ponteiro C cru,a partir de umnp.ndarray
ea partir de umcython.view.array
.Suponha que eu não tenho dados passados para a minha função cython de fora, mas, em vez disso, quero alocar memória e devolvê-lo como umnp.ndarray
Qual dessas opções eu escolhi? Suponha também que o tamanho desse buffer não é uma constante de tempo de compilação, ou seja, não posso alocar na pilha, mas precisariamalloc
para a opção 1.
As 3 opções pareceriam algo assim:
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")
O que é surpreendente para mim é que nos três casos,Cython gera bastante código para a alocação de memória, em particular uma chamada para__Pyx_PyObject_to_MemoryviewSlice_dc_int
. Isso sugere (e eu posso estar errado aqui, meu insight sobre o funcionamento interno do Cython é muito limitado) que ele primeiro cria um objeto Python e, em seguida, "lança" em uma exibição de memória, o que parece sobrecarga desnecessária.
A referência simples não revela revelar muita diferença entre os três métodos, com 2. sendo o mais rápido por uma margem fina.
Qual dos três métodos é recomendado? Ou existe uma opção diferente e melhor?
Questão a seguir: Eu quero finalmente retornar o resultado como umnp.ndarray
, depois de ter trabalhado com essa visão de memória na função. Uma visualização de memória tipificada é a melhor escolha ou eu prefiro usar a interface de buffer antiga como abaixo para criar umandarray
em primeiro lugar?
cdef np.ndarray[DTYPE_t, ndim=1] b = np.empty(N, dtype=np.int32)