【问题标题】:Declaring numpy array and c pointer in cython在 cython 中声明 numpy 数组和 c 指针
【发布时间】:2013-07-10 11:55:39
【问题描述】:

在我的代码中,我通常使用 numpy 数组来连接方法和类。优化我的程序的核心部分,我将 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. Martinot-Lagarde 提出的,所以我对 C 指针和“numpy 指针”进行了计时。代码基本上是

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

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

使用上面的定义,但我添加了“ndim=1,mode='c'”只是为了确保。结果是 someArraySize = 1e8(以毫秒为单位的时间):

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

这就是我从以前/不同的基准测试中大致记得的内容。

【问题讨论】:

  • 如果有人正在阅读这篇文章:现在我开始使用 cython 的类型化内存视图。根据我的经验,它们在性能上非常接近 C 指针(比 numpy 缓冲区更接近)并且更易于使用。事实上,在极少数情况下,我使用 C 指针犯了“小”(因此不容易识别/避免)错误,这使得它们比类型化的内存视图慢。如果可能的话,我真的推荐输入内存视图。

标签: python numpy cython


【解决方案1】:

您实际上在这里声明了两个 numpy 数组,第一个是通用的,第二个具有特定的 dtype。你可以跳过第一行,someArrayBuff 是一个 ndarray。

这给出了:

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

您至少需要两行代码,因为您正在使用 someArrayPointers 并返回 someArrayNumpy,因此您必须声明它们。


附带说明一下,如果您声明数组的类型和维数,您确定指针比 ndarray 快吗?

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

【讨论】:

  • 感谢您的回答,我不知何故认为 numpy.dtype_t 东西是必要的缓冲区。顺便说一句,我在上面添加了一些时间来证明使用 C 指针的合理性。这并不多,但在我的情况下,一般 > 5% 的加速是值得的。
猜你喜欢
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多