これは、特定の問題ではなく、動作を理解するための質問です。
Mathworksは、数値は連続して格納されるため、事前割り当てが重要になると述べています。これは、セル配列には当てはまりません。
それらは、C++ のポインターのベクトルまたは配列に似ていますか?
これは、ポインターが double の半分のサイズであるため、事前割り当てはそれほど重要ではないことを意味します (whos によると - ただし、mxArray のデータ型を格納するためのオーバーヘッドがどこかに確実に存在します)。
このコードの実行:
clear all
n = 1e6;
tic
A = [];
for i=1:n
A(end + 1) = 1;
end
fprintf('Numerical without preallocation %f s\n',toc)
clear A
tic
A = zeros(1,n);
for i=1:n
A(i) = 1;
end
fprintf('Numerical with preallocation %f s\n',toc)
clear A
tic
A = cell(0);
for i=1:n
A{end + 1} = 1;
end
fprintf('Cell without preallocation %f s\n',toc)
tic
A = cell(1,n);
for i=1:n
A{i} = 1;
end
fprintf('Cell with preallocation %f s\n',toc)
戻り値: 事前割り当てなしの数値 0.429240 秒 事前割り当てありの数値 0.025236 秒 事前割り当てなしのセル 4.960297 秒 事前割り当てありのセル 0.554257 秒
数値に驚きはありません。しかし、データ自体ではなくポインターのコンテナーのみが再割り当てを必要とするため、これは私を驚かせました。(ポインターが double よりも小さいため) どちらが <.2s の差につながるはずです。このオーバーヘッドはどこから来るのでしょうか?
関連する質問は、Matlab で異種データ用のデータ コンテナーを作成したい場合です (最初は最終的なサイズがわからないため、事前割り当てはできません)。オーバーヘッドも大きいため、ハンドルクラスは良くないと思います。
すでに何かを学ぶことを楽しみにしています
magu_
編集: Eitan T によって提案されたリンク リストを試してみましたが、matlab のオーバーヘッドはまだかなり大きいと思います。double 配列をデータ (rand(200000,1)) として試してみました。
説明するために小さなプロットを作成しました。
グラフのコード: (回答の投稿に記載されているように、matlab hompage の dlnode クラスを使用しました)
D = ランド (200000,1);
s = linspace(10,20000,50);
nC = zeros(50,1);
nL = zeros(50,1);
for i = 1:50
a = cell(0);
tic
for ii = 1:s(i)
a{end + 1} = D;
end
nC(i) = toc;
a = list([]);
tic
for ii = 1:s(i)
a.insertAfter(list(D));
end
nL(i) = toc;
end
figure
plot(s,nC,'r',s,nL,'g')
xlabel('#iter')
ylabel('time (s)')
legend({'cell' 'list'})
誤解しないでほしいのですが、かなり柔軟なリンク リストがあるので、リンク リストのアイデアが気に入っていますが、オーバーヘッドが大きすぎる可能性があると思います。