2012-12-01 28 views

回答

64

使用repmat是迄今爲止預分配結構的最有效的方法:

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

這是〜10倍的速度更快利用Matlab 2011A不是通過索引預分配,如

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 
     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.我很想知道爲什麼這是真的,如果有人能解釋它。

+0

在問的問題中,字段'x'的值從1增加到100.在答案中,所有實例都是1.您將如何適應這個問題?我在問,因爲我需要這個:) – Mace

+5

你的基準測試存在一個錯誤:在初始化c之前沒有「tic」(雖然它對你的情況並沒有太大的區別,因爲2比3快很多)。然而在Matlab的某些版本(例如2010)中,似乎2)和3)採取相同的時間,不確定新版本中的更改。 – Maxweel

+0

在MATLAB 2017a中,repmat仍然是最快的。 –

11

關於此,在Loren on the Art of MATLAB博客中有一個很好的討論。

如果我理解正確的話,這裏的初始化你想要的一個結構方式:

a(100).x = 100; 

通過這種方法,我們可以看到,元素與空數組填充。

+0

這是迄今爲止我見過的最優雅的解決方案。由於我最關心的是代碼行數,我給出了這個答案+1。 – Hazem

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) 
-1

this answer,也有另一種方式做到這一點:!

[a.x] = deal(val); 

其中val是要分配給的值,每結構的元素。

該命令的效果與其他命令的效果不同,因爲每個結構a的每個x字段都將被賦予val值。

-1

不是預先分配結構數組,它可能更容易反轉循環。通過這種方式,數組在第一次迭代中分配,其餘迭代用於填充結構。

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

這是應該的方式來完成,最簡單的就是

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

如果您修復丟失的「抽動」這種方法添加到由jerad給出的基準測試代碼的方法我提出上述比repmat慢一點,但更簡單的實現,這裏是輸出:

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

即repmat快是因爲每一個「X」字段的值預分配期間分配的原因, inste把它留空的廣告。如果上述預分配技術改變,所以我們開始與分配一個值(一個)中的所有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); 

所有的速度優勢將不復存在