如何加速scipy.weave中的多维数组访问?
我正在把我的C代码嵌入到Python中,以加快循环的速度:
from scipy import weave
from numpy import *
#1) create the array
a=zeros((200,300,400),int)
for i in range(200):
for j in range(300):
for k in range(400):
a[i,j,k]=i*300*400+j*400+k
#2) test on c code to access the array
code="""
for(int i=0;i<200;++i){
for(int j=0;j<300;++j){
for(int k=0;k<400;++k){
printf("%ld,",a[i*300*400+j*400+k]);
}
printf("\\n");
}
printf("\\n\\n");
}
"""
test =weave.inline(code, ['a'])
这工作得很好,但当数组很大的时候,还是挺耗费资源的。有人建议我用.a.strides,而不是那种复杂的“a[i*300*400+j*400+k]”这种写法。我对.strides的文档看不太懂。
有没有什么建议?
提前谢谢你们!
4 个回答
0
在C语言中,没有办法加快访问多维数组的速度。你必须先计算出数组的索引,然后再去获取它的值,这个过程就是这么简单。
1
问题在于,你的C代码正在把240万个数字打印到屏幕上。这当然会花费一些时间,因为这些数字需要先转换成字符串,然后再显示出来。你真的需要把所有数字都打印到屏幕上吗?你的最终目标是什么呢?
为了做个对比,我尝试把另一个数组设置为a中的每个元素。这个过程大约花了0.05秒。而我在尝试打印所有元素到屏幕上时,过了大约30秒就放弃了计时。
4
你可以用下面的代码替换掉这三个for循环:
grid=np.ogrid[0:200,0:300,0:400]
a=grid[0]*300*400+grid[1]*400+grid[2]
根据下面的内容,这样做可能会让速度提高大约68倍(或者更快?见下文):
% python -mtimeit -s"import test" "test.m1()"
100 loops, best of 3: 17.5 msec per loop
% python -mtimeit -s"import test" "test.m2()"
1000 loops, best of 3: 247 usec per loop
这是一个测试文件:test.py:
import numpy as np
n1,n2,n3=20,30,40
def m1():
a=np.zeros((n1,n2,n3),int)
for i in range(n1):
for j in range(n2):
for k in range(n3):
a[i,j,k]=i*300*400+j*400+k
return a
def m2():
grid=np.ogrid[0:n1,0:n2,0:n3]
b=grid[0]*300*400+grid[1]*400+grid[2]
return b
if __name__=='__main__':
assert(np.all(m1()==m2()))
当n1、n2、n3分别设置为200、300、400时,
python -mtimeit -s"import test" "test.m2()"
在我的电脑上运行了182毫秒,
python -mtimeit -s"import test" "test.m1()"
而且还没有完成。