2013-07-10 13 views
7

Nel mio codice ho eseguirne usare matrici NumPy di ​​interfaccia tra metodi e classi. Ottimizzando le parti principali del mio programma uso cython con c puntatori di quegli array numpy. Unforunately, il modo in cui sto attualmente dichiarando gli array è piuttosto lungo.Dichiarazione NumPy matrice ec puntatore Cython

Ad esempio, supponiamo di avere un metodo che dovrebbe restituire un array numpy someArrayNumpy, ma all'interno dei puntatori di funzione * alcuniArrayPoint dovrebbero essere utilizzati per la velocità. Questo è come io di solito dichiaro questo:

cdef: 
    numpy.ndarray someArrayNumpy = numpy.zeros(someArraySize) 
    numpy.ndarray[numpy.double_t, ndim=1] someArrayBuff = someArrayNumpy 
    double *someArrayPointers = <double *> someArrayBuff.data 

[... some Code ...] 

return someArrayNumpy 

Come si può vedere, questa occupa 3 righe di codice per fondamentalmente un array, e spesso devo dichiarare più di tali matrici.

C'è un/modo intelligente più compatto per fare questo? Penso che mi manchi qualcosa.

EDIT:

Così perché è stato chiesto da J. Martinot-Lagarde ho cronometrato puntatori C e "puntatori numpy". Il codice era fondamentalmente

for ii in range(someArraySize): 
    someArrayPointers[ii] += 1 

e

for ii in range(someArraySize): 
    someArrayBuff[ii] += 1 

con le definizioni di cui sopra, ma ho aggiunto "Ndim = 1, mode = 'c'" solo per assicurarsi. I risultati sono per someArraySize = 1e8 (tempo in ms):

testMartinot("cPointers") 
531.276941299 
testMartinot("numpyPointers") 
498.730182648 

Questo è quello che grosso modo ricordo da benchmark precedenti/diverso.

+0

Se qualcuno sta leggendo questo: A questo punto sono passato a utilizzare le visualizzazioni di memoria digitate di cython. Nella mia esperienza sono molto vicini ai puntatori C nelle prestazioni (più vicini al buffer numpy) e molto più facili da usare. In effetti, in alcune rare occasioni ho commesso errori "piccoli" (quindi non facilmente riconoscibili/evitabili) con i puntatori C che li rendevano più lenti delle immagini di memoria digitate. Consiglio vivamente le immagini di memoria digitate se e dove possibile. – oli

risposta

5

Stai in realtà dichiarando due array numpy qui, il primo è generica e la seconda ha una DTYPE specifica. Puoi saltare la prima riga, alcuniArrayBuff è un narray.

Questo dà:

numpy.ndarray[numpy.double_t] someArrayNumpy = numpy.zeros(someArraySize) 
double *someArrayPointers = <double *> someArrayNumpy.data 

Hai bisogno di almeno due righe perché si sta utilizzando someArrayPointers e tornando someArrayNumpy quindi bisogna dichiararli.


Come nota a margine, sei sicuro che i puntatori sono più veloci ndarrays, se si dichiara il tipo e il numero di dimensioni della matrice?

numpy.ndarray[numpy.double_t, ndim=2] someArrayNumpy = numpy.zeros(someArraySize) 
+0

Grazie per la risposta, ho in qualche modo pensato che la roba numpy.dtype_t sia un buffer necessario. A proposito ho aggiunto un po 'di tempo sopra per giustificare l'uso dei puntatori C. Non è molto, ma nel mio caso vale la pena fare un aumento generale del 5%. – oli

+0

Grazie per i parametri di riferimento! –