2013-07-10 108 views
7

在我的代码中,我通常使用numpy数组来在方法和类之间进行接口。优化我的程序的核心部分我使用cython与这些numpy数组的c指针。不幸的是,我目前声明数组的方式非常长。在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.马丁诺特-拉加德我计时C指针和 “numpy的指针”。该代码基本上

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

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

与上面的定义,但我补充说: “NDIM = 1,模式= 'C'”,以确保公正。结果是someArraySize = 1e8(时间以毫秒为单位):

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

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

+0

如果有人正在阅读:现在我开始使用类型的cython记忆体。根据我的经验,它们非常接近C指针(比numpy缓冲区更接近)并且使用起来更容易。事实上,在一些罕见的情况下,我用C指针使得它们比类型化的内存视图更慢,从而导致“小”(因此不容易识别/避免)错误。我真的建议在有可能的情况下输入记忆体视图。 – oli

回答

5

你实际上声明两个numpy的阵列这里,第一个是通用的,第二个有一个特定的D型。你可以跳过第一行,someArrayBuff是一个ndarray。

这给:

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

你,因为你正在使用someArrayPointers并返回someArrayNumpy所以你必须声明它们需要至少两行。


作为一个侧面说明,你确定那个指针是不是ndarrays更快,如果你声明的类型和数组的维数?

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

谢谢你的回答,我以某种方式认为numpy.dtype_t是一个必要的缓冲区。顺便说一句,我添加了一些timit以上,以证明使用C指针。这不是很多,但在我的情况下,加速5%以上是值得的。 – oli

+0

感谢您的基准! –