这是我想要优化的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显示
我想当我尝试初始化零阵列贷款和aggloan时,numpy会减慢我的速度。但我需要运行5000多笔贷款。只是想知道在我定义3d / 2d并返回数组时是否还有其他方法可以避免使用numpy ......
答案 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毫秒。这绝对不是你的瓶颈。简介!