6

これは、特定の問題ではなく、動作を理解するための質問です。

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'})

誤解しないでほしいのですが、かなり柔軟なリンク リストがあるので、リンク リストのアイデアが気に入っていますが、オーバーヘッドが大きすぎる可能性があると思います。

4

1 に答える 1

9

セル配列は、C++ のベクトルまたはポインターの配列に似ていますか?

セル配列では、実際にはさまざまなタイプとサイズのデータ​​を格納できますが、各セルには 112 バイトの一定のオーバーヘッドも追加されます (私の他の回答を参照してください)。これは 8 バイトの double をはるかに超えており、特に例のように大きなセル配列を扱う場合は無視できません。

セル配列は、それぞれがセルの実際の内容を指しているポインターの連続配列として実装されていると想定するのが妥当です。

これは、セル配列コンテナー自体のサイズを実際に変更しなくても、各セルの内容を個別に変更できることを意味します。ただし、これは、セル配列に新しいセルを追加するには動的なストレージ割り当てが必要であることも意味します。これが、セル配列にメモリを事前に割り当てるとパフォーマンスが向上する理由です。

関連する質問は、Matlab で異種データ用のデータ コンテナーを作成したい場合です (最初は最終的なサイズがわからないため、事前割り当てはできません)。

最終的なサイズがわからないことは確かに問題になる可能性がありますが、サポートされている必要な最大サイズ (存在する場合) のセル配列を常に事前に割り当て、最後に空のセルを削除することができます。また、MATLAB でのリンク リストの実装を検討することもお勧めします。

于 2013-07-25T11:08:11.713 に答える