python - Cython numpy 数组索引

标签 python arrays indexing numpy cython

我正在尝试使用 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 

关于python - Cython numpy 数组索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7445769/

相关文章:

linux: ranlib 似乎没有将任何新信息添加到存档文件中?

Python - 从纯文本邮件中提取正文

c++ - 没有明确声明的 int[] 中的 foreach

c - 缺少最后一个 IP 地址

arrays - C++ clang 数组比 clang 向量和 gcc 向量和数组快得多

r - 按顺序找到向量中前 n 个元素的索引 [R]

database - 是否可以为在 View 中转换为 DATE 的 TIMESTAMP 列构建基于 Oracle 函数的索引?

python - 为什么 VSCode 不会在断点处停止调试?

python - 处理数组 : how to avoid a "for" statement

python - 如何从文件创建二维字符列表?