如何在MATLAB中初始化结构数组?

时间:2012-12-01 21:52:42

标签: matlab

如何在MATLAB中预分配结构数组?我想在此示例中预先分配“a”,以便它不会多次调整大小。

a = []
for i = 1:100
  a(i).x = i;
end

7 个答案:

答案 0 :(得分:71)

使用repmat是迄今为止预分配结构的最有效方法:

N = 10000;    
b = repmat(struct('x',1), N, 1 );

使用Matlab 2011a比使用索引预先分配快~~ 10倍,如

N      = 10000;
b(N).x = 1

索引方法仅比未预先分配的方法快一点。

No preallocation:            0.075524    
Preallocate Using indexing:  0.063774
Preallocate with repmat:     0.005234


以下代码,以便您进行验证。

        clear;
        N = 10000;

    %1) GROWING A STRUCT
        tic;
        for ii=1:N
            a(ii).x(1)=1;    
        end
        noPreAll = toc;        

    %2)PREALLOCATING A STRUCT
        tic;
        b = repmat( struct( 'x', 1 ), N, 1 );
        for ii=1:N
            b(ii).x(1)=1;    
        end;  
        repmatBased=toc;        

    %3)Index to preallocate
        tic;
        c(N).x = 1;
        for ii=1:N
            c(ii).x(1)=1;    
        end;  
        preIndex=toc;

        disp(['No preallocation:        ' num2str(noPreAll)])            
        disp(['Preallocate Indexing:    ' num2str(preIndex)])
        disp(['Preallocate with repmat: ' num2str(repmatBased)])

命令窗口中的结果:

No preallocation:        0.075524    
Preallocate Indexing:    0.063774
Preallocate with repmat: 0.0052338
>> 

P.S。如果有人能解释的话,我有兴趣知道为什么会这样。

答案 1 :(得分:11)

Loren on the Art of MATLAB博客中对此进行了很好的讨论。

如果我理解正确,这里有一种初始化所需结构的方法:

a(100).x = 100;

使用这种方法,我们可以看到元素用空数组填充。

答案 2 :(得分:11)

您可以通过多种方式初始化结构。例如,您可以使用struct命令:

a(1:100) = struct('x',[]);

将所有字段x设置为空。

如果您知道哪些数据应该在那里,您还可以使用deal来创建和填充结构

xx = num2cell(1:100);
[a(1:100).x]=deal(xx{:});
a(99).x
ans =
    99

或者您可以再次使用struct(请注意,如果结构的字段应该是单元格数组,则需要将单元格括在大括号中!)

a = struct('x',xx)

答案 3 :(得分:1)

应该这样做的方式,最简单的是

a=struct('x',cell(1,N));

如果你修复了缺失的" tic"并将此方法添加到jerad提供的基准测试代码中,我上面提出的方法比repmat慢一点但实现起来要简单得多,这里是输出:

No preallocation:        0.10137
Preallocate Indexing:    0.07615
Preallocate with repmat: 0.01458
Preallocate with struct: 0.07588

repmat更快的原因是因为每个' x'字段在预分配期间分配,而不是将其留空。如果更改了上述预分配技术,那么我们从分配了值(一)的所有x字段开始,如下所示:

    a=cell(1,N);
    a(:)={1};
    d=struct('x',a);

然后,基准测试改进很多,非常接近或比repmat快一些。差异是如此之小,以至于每次运行它都会改变哪一个更快。这是一个输出示例:

No preallocation:        0.0962
Preallocate Indexing:    0.0745
Preallocate with repmat: 0.0259
Preallocate with struct: 0.0184

相反,如果更改了repmat预分配以将字段设置为空,就像这样

b = repmat( struct( 'x', {} ), N, 1 );

失去了所有的速度优势

答案 4 :(得分:0)

使用 cell2struct 是迄今为止我能想到的最快的方法。只需检查以下代码即可进行比较:

clear;
N = 10000;

cel2s=0;
repm=0;

for i=1:100
a=0.0; b=0.0;

tic;
a = cell2struct(cell(1,N), {'x'}, 1 );
cel2s = cel2s + toc;

tic;
b = repmat(struct('x',1), N, 1 );
repm = repm + toc;
end

disp(['cell2struct preallocation: ', num2str(cel2s/100)]);
disp(['repmat preallocation     : ', num2str(repm/100)]);
disp(['speedup                  : ', num2str(fix( repm/cel2s ) ) , ' X']);

典型结果显示平均加速约 19 倍!与 repmat 方法相比:

cell2struct preallocation: 1.4636e-05
repmat preallocation     : 0.00028794
speedup                  : 19 X

答案 5 :(得分:-1)

根据this answer,还有另一种方法:

[a.x] = deal(val);

其中val是您要分配给结构的每个元素的值。

此命令的效果与其他命令的效果不同,因为每个结构x的每个a字段都将分配val值。

答案 6 :(得分:-1)

不是预先分配结构数组,而是可以更容易地反转循环。通过这种方式,数组在第一次迭代中分配,其余的迭代用于填充结构。

a = []
for i = 100:-1:1
    a(i).x = i;
end