Cython - 定义2d数组

时间:2014-08-10 21:01:38

标签: arrays numpy cython

这是我想要优化的cython代码,

    import cython
    cimport cython
    from libc.stdlib cimport rand, srand, RAND_MAX
    import numpy as np
    cimport numpy as np

    def genLoans(int loanid):
        cdef int i, j, k
        cdef double[:,:,:] loans = np.zeros((240, 20, 1000))
        cdef double[:,:] aggloan = np.zeros((240, 20))
        for j from 0<=j<1000:
            srand(loanid*1000+j)
            for i from 0<=i<240:
                for k from 0<=k<20:
                    loans[i,k,j] = rand()
                    ###some other logics
            aggloan[i,k] += loans[i,k,j]/1000
        return aggloan

cython -a显示

enter image description here 我想当我尝试初始化零阵列贷款和aggloan时,numpy会减慢我的速度。但我需要运行5000多笔贷款。只是想知道在我定义3d / 2d并返回数组时是否还有其他方法可以避免使用numpy ......

1 个答案:

答案 0 :(得分:4)

黄色部分是因为Numpy调用,您在其中分配数组。你可以做的是将这些数组作为参数传递给函数,并从一个到另一个重用它们。

另外,我看到你正在重写所有元素,所以你要求记忆,用零写,然后输入你的数字。如果您确定要覆盖所有元素,则可以使用np.empty,这不会初始化变量。

  

注意:Linux内核有一种特定的方式来分配初始化为0的内存,这比其他任何值都快,现代Numpy可以使用它,但它仍然比empty慢:

In [4]: %timeit np.zeros((100,100))
100000 loops, best of 3: 4.04 µs per loop

In [5]: %timeit np.ones((100,100))
100000 loops, best of 3: 8.99 µs per loop

In [6]: %timeit np.empty((100,100))
1000000 loops, best of 3: 917 ns per loop

最后但同样重要的是,您确定这是您的瓶颈吗?我不知道你在做什么处理,但黄色是C代码的行数,而不是时间。无论如何,从时间上看,使用empty应该加快四倍。如果您想要更多,请将其余代码发布在CR。

修改

扩展我的第二句:你的功能签名可以是

def genLoans(int loanid, cdef double[:,:,:] loans,  cdef double[:,:] aggloan):

在循环之前初始化数组,然后一次又一次地传递它们。

在任何情况下,在我的机器(Linux Intel i5)中,它需要9μs,所以你总共花费45毫秒。这绝对不是你的瓶颈。简介!