昨天我在测试使用for循环将数组中的元素相加是否比使用内置的MATLAB函数和更糟糕(据我所知,应该是这样,因为内置函数是预先编译的),但我得到了一些奇怪的结果:
r = rand(1e8, 1);
tic
sum1 = 0;
for i = 1:1e8
sum1 = sum1 + r(i);
end
t1 = toc;
tic
sum2 = sum(r);
t2 = toc;
>> t1
t1 =
0.5872
>> t2
t2 =
0.1053
它给了我这些结果(MATLAB 2011)。然而,我在MATLAB 2013中测试了它,使用sum比for循环更糟糕。我不知道是我搞砸了还是我错过了什么?
哪个更好?循环还是求和?
function timing_builtins()
% Setup
rng(123);
r = rand(1e8, 1);
function test1(r)
sum1 = 0;
for i = 1:1e8
sum1 = sum1 + r(i);
end
end
function test2(r)
sum2 = sum(r);
end
t1 = timeit(@() test1(r));
t2 = timeit(@() test2(r));
format long g;
fprintf('For loop: %f secondsn', t1);
fprintf('Sum call: %f secondsn', t2);
end
这应该可以让您更好地了解加速,在这种特定情况下,sum
大约是for
的10倍。
如果我们调用预定义的变量r
,我们可以看到内置的sum
确实比for
循环快,因子为4。
内置几乎总是更快的选择。BLAST发动机最近进行了大修,降低了这个系数(我使用的是2012a),但对于完全相同的操作,内置通常会更快。使用bsxfun
对事物进行矢量化也是如此,这也(几乎)总是比使用循环更快。
更普遍的问题的答案是;这取决于情况"有时循环会更快,因为它们不会像通用内置那样完成所有的错误检查和类型转换。
多亏了@Daniel和@rayryeng,在最新的MATLAB版本中,对sum
的调用似乎确实更快了。原因是sum
几乎不需要检查,因为在求和元素时不会出现太多错误。此外,sum
本机还从LAPACK/SuiteParse接口调用一个经过高度优化的函数。