2013-07-10 17 views
7

W moim kodzie używam numpy tablic do interfejsu między metodami i klasami. Optymalizując główne części mojego programu Używam cytonu z c wskaźnikami tych numpy tablic. Niestety, sposób, w jaki obecnie deklaruję tablice, jest dość długi.Zgłaszanie numpy array i wskaźnika c w cython

Na przykład, powiedzmy, że mam metodę, która powinna zwrócić tablicę numpy someArrayNumpy, ale wewnątrz wskaźników funkcji * niektóreArrayPointers powinny być używane do prędkości. Jest to, jak zwykle deklarują to:

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 

Jak widać, to zajmuje 3 linii kodu na zasadzie jednej tablicy, a często muszę deklarować więcej z tych tablic.

Czy istnieje bardziej kompaktowy/sprytny sposób na zrobienie tego? Chyba coś mi brakuje.

EDIT:

Więc dlatego, że został poproszony przez J. Martinot-Lagarde I planowane wskaźniki C i "NumPy wskazówek". Kod był w zasadzie

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

i

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

z definicjami z powyżej, ale dodałem "ndim = 1, tryb = 'c'" tylko upewnić. Wyniki są dla someArraySize = 1E8 (czas w ms):

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

To właśnie mniej więcej pamiętam z poprzednich/inny punkt odniesienia.

+0

Jeśli ktokolwiek czyta to: Do ​​tej pory zacząłem używać maszynopisu z cytonami. Z mojego doświadczenia wynika, że ​​są one bardzo zbliżone do wskaźników C w zakresie wydajności (bliżej niż do bufora numpy) i znacznie łatwiejsze w użyciu. Rzeczywiście, w rzadkich przypadkach robiłem "małe" (a więc niełatwe do rozpoznania/możliwe do uniknięcia) pomyłki przy pomocy wskaźników C, które czyniły je wolniejszymi niż typowane widoki pamięci. Naprawdę polecam wpisane widoki pamięci, jeśli i gdzie to możliwe. – oli

Odpowiedz

5

W rzeczywistości deklarujesz tutaj dwa niepoprawne tablice, pierwszy jest generyczny, a drugi ma określony typ dtype. Możesz pominąć pierwszą linię, someArrayBuff jest ndarray.

Daje:

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

Trzeba co najmniej dwie linie, ponieważ używasz someArrayPointers i powrocie someArrayNumpy więc trzeba je zadeklarować.


Na marginesie, jesteś pewien, że wskaźniki są szybsze niż ndarrays, jeśli zadeklarować rodzaj i liczbę wymiarów tablicy?

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

Dziękuję za odpowiedź, jakoś pomyślałem, że rzeczy numpy.dtype_t to niezbędny bufor. Przy okazji dodałem trochę czasu, aby uzasadnić użycie wskaźników C. To niewiele, ale w moim przypadku ogólne przyspieszenie o 5% jest warte wysiłku. – oli

+0

Dziękujemy za testy porównawcze! –