Jaki jest zalecany sposób przydzielania pamięci na widok pamięci wpisanej?

TheDokumentacja Cythona dotycząca widoków wpisanej pamięci wypisz trzy sposoby przypisywania do widoku pamięci wpisanej:

z surowego wskaźnika C,odnp.ndarray iodcython.view.array.

Załóżmy, że nie mam danych przekazanych do mojej funkcji cython z zewnątrz, ale zamiast tego chcę przydzielić pamięć i zwrócić ją jakonp.ndarray, którą z tych opcji wybrałem? Załóżmy również, że rozmiar tego bufora nie jest stałą czasu kompilacji, tj. Nie mogę przydzielić na stosie, ale musiałbymmalloc dla opcji 1.

Trzy opcje wyglądałyby więc następująco:

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")

Co mnie dziwi, to we wszystkich trzech przypadkachCython generuje sporo kodu na alokację pamięci, w szczególności na wywołanie__Pyx_PyObject_to_MemoryviewSlice_dc_int. Sugeruje to (i mogę się tutaj mylić, mój wgląd w wewnętrzne funkcjonowanie Cythona jest bardzo ograniczony), że najpierw tworzy obiekt Pythona, a następnie „rzuca” go do widoku pamięci, co wydaje się niepotrzebne.

A prosty benchmark nie ujawnia znaczącej różnicy między tymi trzema metodami, przy czym 2. jest najszybsza przy niewielkim marginesie.

Która z trzech metod jest zalecana? Czy istnieje inna, lepsza opcja?

Dalsze pytanie: Chcę w końcu zwrócić wynik jakonp.ndarray, po przepracowaniu tego widoku pamięci w funkcji. Czy typowy widok pamięci jest najlepszym wyborem, czy raczej użyję starego interfejsu bufora, jak poniżej, aby utworzyćndarray na pierwszym miejscu?

cdef np.ndarray[DTYPE_t, ndim=1] b = np.empty(N, dtype=np.int32)

questionAnswers(2)

yourAnswerToTheQuestion