昨天我正在测试是否使用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循环更差。我不知道我是搞砸了还是错过了什么?
哪个更好? for loop还是sum?
答案 0 :(得分:1)
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 seconds\n', t1);
fprintf('Sum call: %f seconds\n', t2);
end
这可以让您更好地了解加速,在此特定情况下sum
的{{1}}约为10倍。
如果我们调用预定义变量for
,我们可以看到内置r
确实比sum
循环更快,因子为4。
内置插件几乎总是更快的选择。 BLAST引擎最近已经彻底改变了这个因素(我使用了2012a),但对于完全相同的操作,内置通常会更快。同样适用于使用for
对事物进行矢量化,这也会(几乎)总是比使用循环更快。
更一般的问题的答案是,"它取决于。"有时循环更快,因为它们不会执行所有错误检查和类型转换,这是广义内置的。
感谢@Daniel和@rayryeng,似乎对bsxfun
的调用在最新的MATLAB版本中确实更快。原因是sum
几乎不需要检查,因为在求和元素方面没有太多可能出错的地方。此外,sum
本机从LAPACK / SuiteSparse接口调用一个函数,该接口经过高度优化。