我在同一台机器上运行python 2.7和matlab R2010a,什么都不做,它给了我10倍的速度
我在网上看了,听说应该是同一个订单。 Python将进一步减慢,就像for循环中的语句和数学运算符一样
我的问题:这是现实吗?还是有其他方式让他们以相同的速度顺序?
这是python代码
import time
start_time = time.time()
for r in xrange(1000):
for c in xrange(1000):
continue
elapsed_time = time.time() - start_time
print 'time cost = ',elapsed_time
Output: time cost = 0.0377440452576
这是matlab代码
tic
for i = 1:1000
for j = 1:1000
end
end
toc
Output: Escaped time is 0.004200 seconds
答案 0 :(得分:8)
发生这种情况的原因与JIT编译器有关,它正在优化MATLAB for循环。您可以使用feature accel off
和feature accel on
禁用/启用JIT加速器。禁用加速器时,时间会发生显着变化。
MATLAB with accel on:Elapsed time is 0.009407 seconds.
MATLAB with accel off:Elapsed time is 0.287955 seconds.
python:time cost = 0.0511920452118
因此,JIT加速器直接导致您注意到的加速。您应该考虑另一件事,这与您定义迭代索引的方式有关。在MATLAB和python这两种情况下,您都使用迭代器来定义循环。在MATLAB中,您可以通过添加方括号([]
)来创建实际值,而在python中,您使用range
而不是xrange
。进行这些更改时
% MATLAB
for i = [1:1000]
for j = [1:1000]
# python
for r in range(1000):
for c in range(1000):
时代成为
MATLAB with accel on:Elapsed time is 0.338701 seconds.
MATLAB with accel off:Elapsed time is 0.289220 seconds.
python:time cost = 0.0606048107147
最后一个考虑因素是你是否要在循环中添加一个快速计算。即t=t+1
。然后时间成为
MATLAB with accel on:Elapsed time is 1.340830 seconds.
MATLAB with accel off:Elapsed time is 0.905956 seconds.
(Yes off更快)
python:time cost = 0.147221088409
我认为这里的道德观点是,开环即用的for循环的计算速度与极其简单的循环相当,具体取决于具体情况。然而,python中还有其他一些数值工具可以显着加快速度,numpy和PyPy到目前为止已经提出。
答案 1 :(得分:3)
基本的Python实现CPython并不意味着超级快速。如果您需要高效的matlab风格的数值操作,请使用the numpy
package或专为快速工作而设计的Python实现,例如PyPy甚至Cython。 (在C中编写Python扩展,当然速度非常快,也是一种可能的解决方案,但在这种情况下,您也可以使用numpy
并省去自己的努力。)
答案 2 :(得分:2)
如果Python执行性能对您至关重要,您可以查看PyPy
我做了你的测试:
import time
for a in range(10):
start_time = time.time()
for r in xrange(1000):
for c in xrange(1000):
continue
elapsed_time = time.time()-start_time
print elapsed_time
使用标准Python 2.7.3,我得到:
0.0311839580536
0.0310959815979
0.0309510231018
0.0306520462036
0.0302460193634
0.0324130058289
0.0308878421783
0.0307397842407
0.0304911136627
0.0307500362396
然而,使用PyPy 1.9.0(对应于Python 2.7.2),我得到:
0.00921821594238
0.0115230083466
0.00851202011108
0.00808095932007
0.00496387481689
0.00499391555786
0.00508499145508
0.00618195533752
0.005126953125
0.00482988357544
PyPy的加速真的令人惊叹,当它的JIT编译器优化超过它们的成本时真的变得可见。这也是我引入额外for循环的原因。对于此示例,绝对不需要修改代码。
答案 3 :(得分:0)
这只是我的看法,但我认为过程要复杂一些。基本上,Matlab是C的优化层,因此通过适当地初始化矩阵和最小化函数调用(在Matlab中避免使用“。”对象之类的运算符),您可以获得截然不同的结果。考虑具有余弦函数的波形发生器的以下简单示例。在实际的调试会话中,Matlab时间= 0.15秒,在实际的调试会话(Spyder)中,Python时间= 25秒,因此Python变慢了166倍。直接由Python 3.7.4运行。机器的时间大约是5秒,因此仍然是不可忽略的33x。
MATLAB:
AW(1,:) = [800 , 0 ]; % [amp frec]
AW(2,:) = [300 , 4E-07];
AW(3,:) = [200 , 1E-06];
AW(4,:) = [ 50 , 4E-06];
AW(5,:) = [ 30 , 9E-06];
AW(6,:) = [ 20 , 3E-05];
AW(7,:) = [ 10 , 4E-05];
AW(8,:) = [ 9 , 5E-04];
AW(9,:) = [ 7 , 7E-04];
AW(10,:)= [ 5 , 8E-03];
phas = 0
tini = -2*365 *86400; % 2 years backwards in seconds
dt = 200; % step, 200 seconds
tfin = 0; % present
vec_t = ( tini: dt: tfin)'; % vector_time
nt = length(vec_t);
vec_t = vec_t - phas;
wave = zeros(nt,1);
for it = 1:nt
suma = 0;
t = vec_t(it,1);
for iW = 1:size(AW,1)
suma = suma + AW(iW,1)*cos(AW(iW,2)*t);
end
wave(it,1) = suma;
end
PYTHON:
import numpy as np
AW = np.zeros((10,2))
AW[0,:] = [800 , 0.0]
AW[1,:] = [300 , 4E-07]; # [amp frec]
AW[2,:] = [200 , 1E-06];
AW[3,:] = [ 50 , 4E-06];
AW[4,:] = [ 30 , 9E-06];
AW[5,:] = [ 20 , 3E-05];
AW[6,:] = [ 10 , 4E-05];
AW[7,:] = [ 9 , 5E-04];
AW[8,:] = [ 7 , 7E-04];
AW[9,:] = [ 5 , 8E-03];
phas = 0
tini = -2*365 *86400 # 2 years backwards
dt = 200
tfin = 0 # present
nt = round((tfin-tini)/dt) + 1
vec_t = np.linspace(tini,tfin1,nt) - phas
wave = np.zeros((nt))
for it in range(nt):
suma = 0
t = vec_t[fil]
for iW in range(np.size(AW,0)):
suma = suma + AW[iW,0]*np.cos(AW[iW,1]*t)
#endfor iW
wave[it] = suma
#endfor it
要处理Python中的这些方面,我建议直接编译为可执行文件,以将可能损害项目的数字部分二进制化(或将C或Fortran转换为可执行文件,然后由Python调用)。当然,其他建议也值得赞赏。