2013-07-10 72 views
7

在我的代碼中,我通常使用numpy數組來在方法和類之間進行接口。優化我的程序的核心部分我使用cython與這些numpy數組的c指針。不幸的是,我目前聲明數組的方式非常長。在cython中聲明numpy數組和c指針

例如,假設我有應該返回一個numpy的陣列someArrayNumpy的方法,但是函數指針內* someArrayPointers應該用於速度。這就是我通常這樣聲明:

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 

正如你所看到的,這個佔用3行代碼基本上一個陣列,而且往往我要宣佈更多的陣列。

是否有一個更緊湊的/聰明的方式做到這一點?我想我錯過了一些東西。

編輯:

,是因爲它被要求J.馬丁諾特-拉加德我計時C指針和 「numpy的指針」。該代碼基本上

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

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

與上面的定義,但我補充說: 「NDIM = 1,模式= 'C'」,以確保公正。結果是someArraySize = 1e8(時間以毫秒爲單位):

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

這就是我從之前/不同的基準測試中大致記得的。

+0

如果有人正在閱讀:現在我開始使用類型的cython記憶體。根據我的經驗,它們非常接近C指針(比numpy緩衝區更接近)並且使用起來更容易。事實上,在一些罕見的情況下,我用C指針使得它們比類型化的內存視圖更慢,從而導致「小」(因此不容易識別/避免)錯誤。我真的建議在有可能的情況下輸入記憶體視圖。 – oli

回答

5

你實際上聲明兩個numpy的陣列這裏,第一個是通用的,第二個有一個特定的D型。你可以跳過第一行,someArrayBuff是一個ndarray。

這給:

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

你,因爲你正在使用someArrayPointers並返回someArrayNumpy所以你必須聲明它們需要至少兩行。


作爲一個側面說明,你確定那個指針是不是ndarrays更快,如果你聲明的類型和數組的維數?

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

謝謝你的回答,我以某種方式認爲numpy.dtype_t是一個必要的緩衝區。順便說一句,我添加了一些timit以上,以證明使用C指針。這不是很多,但在我的情況下,加速5%以上是值得的。 – oli

+0

感謝您的基準! –