在python和matlab中填充矩阵的速度

时间:2013-12-03 10:44:22

标签: python performance matlab python-2.7 numpy

与Matlab相比,我正在测试Python的速度。我决定转向Python,因为它有很多优点,但我想比较速度,看看这方面有什么不同。

我测试了一些for循环来填充1000 x 1000矩阵,如下所示:

from numpy import *

sizeM = 1000
y = zeros((sizeM,sizeM))
x = 4
tic = time.clock()

for i in range(sizeM):
    for j in range(sizeM):
        y[i,j] = cos(i*j) + i * sin(x**2);

toc = time.clock()
time = toc-tic
以这种方式

time 5.93 sseconds 。但在Matlab中,使用以下代码只需 0.11秒

tic
sizeM = 1000;
y = zeros(sizeM);
x =4;
for i = 1:sizeM
     for j = 1:sizeM
         y(i,j) = cos(i*j) + i * sin(x^2);
     end
end

toc

我的问题是:

这是对的吗?

Matlab是否比Python更快地执行嵌套for循环?或者我在这里做错了什么?

感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

我希望您知道在两种语言中都应该编写矢量化代码!

  1. 我相信Matlab有一个及时的加速器,它可能会为这样的表达式提供支持,我不确定如果你在内部循环中调用自己的函数会发生什么。
  2. 循环本身并不是一切,大多数时候内部循环内部更重要。因此,如果嵌套循环更慢或更快,整个问题可能通常是错误的问题。
  3. 编写NumPy以使用数组。给它这样的标量增加了很多开销,如果你真的想使用浮动标量(你不应该因为你可以对操作进行矢量化),你也可以使用math.sin ......
  4. 无论如何,比较矢量化代码:

    i, j = np.ogrid[:1000,:1000] # or whatever else you want to use
    y = np.cos(i * j) + i * np.sin(x**2)
    

    可能你可以进一步优化它,但这应该没关系。


    由于似乎讨论可能从这里开始,我不确定scalars的matlab开销是多少,可能非常小(当然还有成功的JIT),但这可以解释为什么这个代码snipplet可能会因为numpy而变慢。请不要语言比较...

    可以安全地说的是,特别是如果JIT在matlab中启动,有必要在NumPy中尝试更难的矢量化(或端口到编译语言,这在两者中都很有效)。

答案 1 :(得分:2)

答案是你真的没有在这里测试嵌套循环。 大部分时间不会用于循环,而是用于评估循环中的表达式。

如果你想测试循环和填充矩阵,你可以做一些更微不足道的事情:

from numpy import *

sizeM = 1000
y = zeros((sizeM,sizeM))
x = 4
tic = time.clock()

for i in range(sizeM):
    for j in range(sizeM):
        y[i,j] = 1;

toc = time.clock()
time = toc-tic

与:相比:

sizeM = 1000;
y = zeros(sizeM);
x =4;
tic
for i = 1:sizeM
     for j = 1:sizeM
         y(i,j) = 1;
     end
end
toc

答案 2 :(得分:0)

JIT compiler有助于优化MATLAB for循环(Python也支持某些形式的JIT编译)。您可以使用feature accel offfeature accel on禁用/启用JIT加速器,然后使用以下代码再次测试。 的Python:

import time    
sizeM = 1000

tic = time.clock()

for i in range(sizeM):
   for j in range(sizeM):
      pass

toc = time.clock()
time = toc-tic
print time

Matlab test1:

sizeM = 1000;
tic
for i = 1:sizeM
   for j = 1:sizeM
     ;
   end
end
toc

Matlab test2:

sizeM = 1000;
tic
for i = [1:sizeM]
   for j = [1:sizeM]
     ;
   end
end
toc

如果您愿意,还可以比较range(sizeM)xrange(sizeM)的速度。