Was ist die empfohlene Methode zum Zuweisen von Speicher für eine typisierte Speicheransicht?

DasCython-Dokumentation zu typisierten Speicheransichten Nennen Sie drei Möglichkeiten zum Zuweisen zu einer typisierten Speicheransicht:

von einem rohen C-Zeiger,von einemnp.ndarray undvon einemcython.view.array.

Angenommen, ich habe keine Daten von außen an meine Cython-Funktion übergeben, sondern möchte Speicher zuweisen und als zurückgebennp.ndarrayWelche dieser Optionen wähle ich? Es sei auch angenommen, dass die Größe dieses Puffers keine Konstante zur Kompilierungszeit ist, d. H., Ich kann keine Zuordnung zum Stapel vornehmen, müsste dies aber tunmalloc für Option 1.

Die 3 Optionen sehen also ungefähr so ​​aus:

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

Was mich überrascht ist, dass in allen drei FällenCython generiert ziemlich viel Code für die Speicherzuordnung, insbesondere einen Anruf an__Pyx_PyObject_to_MemoryviewSlice_dc_int. Dies legt nahe (und ich könnte hier falsch liegen, da meine Einsichten in die Funktionsweise von Cython sehr begrenzt sind), dass zuerst ein Python-Objekt erstellt und es dann in eine Speicheransicht "gewandelt" wird, was unnötig zu sein scheint.

A einfacher Benchmark zeigt nicht viel Unterschied zwischen den drei Methoden, mit 2. ist die schnellste mit einem schmalen Rand.

Welche der drei Methoden wird empfohlen? Oder gibt es eine andere, bessere Option?

Zusatzfrage: Ich möchte das Ergebnis endlich als zurückgebennp.ndarray, nachdem Sie mit dieser Speicheransicht in der Funktion gearbeitet haben. Ist eine getippte Speicheransicht die beste Wahl oder würde ich lieber einfach die alte Pufferschnittstelle wie unten angegeben verwenden, um eine zu erstellenndarray an erster Stelle?

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

Antworten auf die Frage(2)

Ihre Antwort auf die Frage