Matlab预分配与不分配,第二个更快,为什么?

时间:2012-12-24 15:14:14

标签: performance matlab

大约三个月前,我在Matlab运行了一个样本,发生了一些奇怪的事情。今天,我正在测试我的另一个问题(How can I sort the elements of a cell?)的答案。它是关于Matlab中的预分配。让我解释一下:

考虑这个测试代码,我们尝试以三种方式创建矩阵(ones(100,100)):

  1. 没有预先分配(声明I=[]
  2. 预先分配(声明I=zeros(100,100)
  3. 根本没有分配(我没有声明)
  4. 代码:

    N=1000;
    sum0=0;sum1=0;sum2=0;
    for q=1:N
    
        % No pre-allocating
        tic
        I=[];
        for i=1:100
            for j=1:100
                I(i,j)=1;
            end
        end
        a=toc;sum0=sum0+a;
    
        % with pre-allocation
        tic
        I=zeros(100,100);
        for i=1:100
            for j=1:100
                I(i,j)=1;
            end
        end
        a=toc;sum1=sum1+a;
    
        % if nothing is declared, I call it no-allocation
        tic
        for i=1:100
            for j=1:100
                I(i,j)=1;
            end
        end
        a=toc;sum2=sum2+a;
    end
    

    结果是:

    sum0 =1.53790886830589    //no pre-allocation
    sum1 = 0.127538555877912  //with pre-allocation
    sum2 = 0.120887850271473  //no allocation
    

    第三种方法(我不写I=[]I=zeros(100,100))是最好的方法!这也发生在我之前的question。 (见更新部分)

    此方法与第一个和第二个方法有什么区别?

1 个答案:

答案 0 :(得分:4)

第三次运行循环时,工作区中已存在I。因此,循环与第二个循环一样快,除了你不再调用zeros

我建议第二次和第三次用IJ替换K以避免在计算时间时出错(或在每次循环之前调用clear I;感谢@EitanT)

编辑作为替代方案,您可以使用隐式预分配,向后循环,以便分配的第一个元素定义整个数组:

for i=100:-1:1
    for j=100:-1:1
       I(i,j) = 1;
    end
end