【问题标题】:Cython: Effectively using Numpy in Pure Python ModeCython:在纯 Python 模式下有效地使用 Numpy
【发布时间】:2021-06-16 14:34:01
【问题描述】:

我对使用 Cython 很陌生,我对使用“纯 Python”模式很感兴趣。

我现在正在做的工作广泛使用 numpy,并且知道有一个用于 numpy 的 C api,我很高兴看到它可以做什么。

作为一个小测试,我将两个小测试文件放在一起,test.pytest.pxd。它们的内容如下:

test.py:

import cython
import numpy as np

@cython.locals(array=np.ndarray)
@cython.returns(np.ndarray)
def test(array):
    return np.cumsum(array)

test_array = np.array([1,2,3,4,5])
test(test_array)

test.pxd:

# cython: language_level=3
cimport numpy as np

cdef np.ndarray test(np.ndarray array)

然后我用cython -a test.py 编译这些文件,希望在调用np.cumsum() 时我几乎看不到python 交互。然而,当我检查生成的 HTML 文件时,我发现了以下内容:

由此看来,我对 np.cumsum 的调用似乎与 python 进行了大量交互,这让人感觉很反直觉。我的期望是,因为我(应该)使用 cimported numpy,所以应该很少有 python 交互。

我的问题是“我的直觉正确吗?”。我是否对我的文件进行了错误设置,不允许 cimported numpy 实际用于函数调用,这就是为什么我仍然看到这么多黄色的原因?还是我从根本上误解了什么。

感谢阅读!

【问题讨论】:

  • 您使用的是导入功能,而不是 cimported 功能。使用“cimport numpy as cnp”查看差异。
  • 阅读后我认为这不是解决方案@ead,似乎会导致编译错误:'cimported module has no attribute "cumsum"'。在下面的帖子之后,似乎 cimport 只能让您访问预定义的类型,而不是 numpy 函数的 c 版本。 stackoverflow.com/questions/53026820/…
  • 这只是一个解释,为什么你会看到 python 开销,而不是加速事情的方法。如果 cumsum 没有 c-api 版本,你将不得不支付这个开销。

标签: python numpy cython


【解决方案1】:

将类型定义为np.ndarray 主要改进了一件事:它使索引它们以显着更快地获取单个值。几乎其他一切都保持相同的速度。

np.cumsum(和任何其他 Numpy 函数)通过​​标准 Python 机制调用并以完全相同的速度运行(当然,它在内部是用 C 实现的,应该很快)。数学运算符(如 add+, -, *, etc.)也通过 Python 调用并且保持相同的速度。

实际上,您的包装可能会使其变慢 - 它添加了不必要的类型检查(以确保数组是 np.ndarray)和额外的间接层。

在这里打字没有任何收获。

【讨论】:

  • 我可以理解打字在这里并没有真正让我得到任何东西(谢谢你的回答顺便说一句!)。我现在不太清楚的是 numpy 的 cimported 版本的目的。由于 numpy 主要是用 C 编写的,我的想法是 numpy 的 cimported 版本旨在减少 python 交互的数量,而不是更改 numpy 后端中的任何内容。如果不是这样,cimporting 究竟能给我们带来什么?
  • 目的是让你做arr[x](索引单个元素),并使其快速。在一个可以大幅度提高速度的循环中。它主要帮助不容易向量化的算法
  • 感谢您的回答。我做了更多的挖掘并找到了下面链接的文档。代码片段中的 cmets 特别有帮助,请按照您对 T 说的内容进行操作。cython.readthedocs.io/en/latest/src/tutorial/numpy.html
猜你喜欢
  • 1970-01-01
  • 2014-07-10
  • 2014-03-06
  • 2021-08-28
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 2016-02-25
  • 2014-01-19
相关资源
最近更新 更多