使用 tic toc 作为基准 MATLAB

Using tic toc for benchmark MATLAB

昨天我在测试是否使用 for 循环将数组中的元素相加比使用内置的 MATLAB 函数 sum 更糟糕(据我所知应该是这样,因为内置函数是预先-编译),但是我得到了一些奇怪的结果:

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 循环或求和?

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 大约是 for 的 10 倍。

如果我们改为调用预定义变量 r,我们可以看到内置 sum 确实比 for 循环快 4 倍。

内置几乎总是更快的选择。 BLAST 引擎最近进行了大修,减少了这个因素(我使用 2012a),但对于完全相同的操作,内置通常会更快。这同样适用于使用 bsxfun 对事物进行矢量化,这也(几乎)总是比使用循环更快。

引用@beaker:

更笼统的问题的答案是“视情况而定”。有时循环速度更快,因为它们不执行通用内置函数会执行的所有错误检查和类型转换。

感谢@Daniel 和@rayryeng,在最新的 MATLAB 版本中,对 sum 的调用似乎确实更快。这样做的原因是 sum 几乎不需要检查,因为在求和元素时不会出错。此外,sum 本机从 LAPACK / SuiteSparse 接口调用函数,该接口经过高度优化。