簡體   English   中英

Cython numpy數組索引

[英]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.arrayorder參數,使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM