[英]Cython numpy array indexing
我正在嘗試使用cython來加速一些python代碼,我正在使用cython的-a
選項來查看我可以改進的地方。 我的理解是,在生成的html文件中,突出顯示的行是調用python函數的行 - 這是正確的嗎?
在下面的簡單函數中,我使用緩沖區語法聲明了numpy數組參數arr
。 我認為這允許索引操作純粹在C中進行,而不必調用python函數。 但是, cython -a
(版本0.15)突出顯示了我設置arr
元素值的行,盡管不是我讀取其中一個元素的行。 為什么會這樣? 有沒有更有效的方式來訪問numpy數組元素?
import numpy
cimport numpy
def foo(numpy.ndarray[double, ndim=1] arr not None):
cdef int i
cdef double elem
for i in xrange(10):
elem = arr[i] #not highlighted
arr[i] = 1.0 + elem #highlighted
編輯:另外, mode
緩沖區參數如何與numpy交互? 假設我沒有從默認值更改numpy.array
的order
參數,使用mode='c'
總是安全嗎? 這實際上對性能產生了影響嗎?
在delnan評論之后編輯: arr[i] += 1
也會突出顯示(這就是為什么我首先將其拆分,以查看操作的哪個部分導致了問題)。 如果我關閉邊界檢查以簡化事情(這與突出顯示的內容沒有區別),生成的c代碼為:
/* "ct.pyx":11
* cdef int i
* cdef double elem
* for i in xrange(10): # <<<<<<<<<<<<<<
* elem = arr[i]
* arr[i] = 1.0 + elem
*/
for (__pyx_t_1 = 0; __pyx_t_1 < 10; __pyx_t_1+=1) {
__pyx_v_i = __pyx_t_1;
/* "ct.pyx":12
* cdef double elem
* for i in xrange(10):
* elem = arr[i] # <<<<<<<<<<<<<<
* arr[i] = 1.0 + elem
*/
__pyx_t_2 = __pyx_v_i;
__pyx_v_elem = (*__Pyx_BufPtrStrided1d(double *, __pyx_bstruct_arr.buf, __pyx_t_2, __pyx_bstride_0_arr));
/* "ct.pyx":13
* for i in xrange(10):
* elem = arr[i]
* arr[i] = 1.0 + elem # <<<<<<<<<<<<<<
*/
__pyx_t_3 = __pyx_v_i;
*__Pyx_BufPtrStrided1d(double *, __pyx_bstruct_arr.buf, __pyx_t_3, __pyx_bstride_0_arr) = (1.0 + __pyx_v_elem);
}
答案是熒光筆愚弄讀者。 我編譯了你的代碼,高亮下生成的指令是處理錯誤情況和返回值所需的指令,它們與數組賦值無關。
確實,如果您將代碼更改為:
def foo(numpy.ndarray[double, ndim=1] arr not None):
cdef int i
cdef double elem
for i in xrange(10):
elem = arr[i]
arr[i] = 1.0 + elem
return # + add this
重點將放在最后一行,而不是更多。
您可以使用@ cython.boundscheck進一步加快代碼速度:
import numpy
cimport numpy
cimport cython
@cython.boundscheck(False)
def foo(numpy.ndarray[double, ndim=1] arr not None):
cdef int i
cdef double elem
for i in xrange(10):
elem = arr[i]
arr[i] = 1.0 + elem
return
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.