Matlabで要素を削除するこれら2つの方法に違いはありますか:
ElementsToDelete = [0 0 1 0 1 0 0 1 1 0]
A = 1:10
A(ElementsToDelete) = []
%Versus
A = 1:10
A = A(~ElementsToDelete)
ある方法が他の方法よりも適切な場合はありますか? 効率に違いはありますか?それとも完全に交換可能ですか?
Matlabで要素を削除するこれら2つの方法に違いはありますか:
ElementsToDelete = [0 0 1 0 1 0 0 1 1 0]
A = 1:10
A(ElementsToDelete) = []
%Versus
A = 1:10
A = A(~ElementsToDelete)
ある方法が他の方法よりも適切な場合はありますか? 効率に違いはありますか?それとも完全に交換可能ですか?
これを試して:
A = rand(1e3, 1);
b = A<0.5;
tic;
for ii = 1:1e5
a = A;
a(b) = [];
end
toc
tic;
for ii = 1:1e5
a = A;
a = a(~b);
end
toc
結果:
Elapsed time is 1.654146 seconds
Elapsed time is 1.126325 seconds
したがって、違いは、再割り当てを支持する 1.5 の速度係数です。ただし、これはさらに悪いことです。
A = rand(1e4, 1);
stop = 0;
for jj = 1:10
a = A;
start = tic;
for ii = 1:1e5
a(a < rand) = [];
end
stop = stop + toc(start);
end
avg1 = stop/10
stop = 0;
for jj = 1:10
a = A;
start = tic;
for ii = 1:1e5
a = a(a > rand);
end
stop = stop + toc(start);
end
avg2 = stop/10
avg1/avg2
結果:
avg1 = 1.1740235 seconds
avg2 = 0.1850463 seconds
avg1/avg2 = 6.344485136963019
したがって、係数は 6 を優に超えます。
私の推測では、削除 (つまり、 での代入)は、論理インデックスを介して内部ループ内[]
の a の出現ごとに配列全体を再書き込みします。true
このようにテストすると明らかになるように、これは絶望的に非効率的です。一方、再割り当てでは、新しい配列のサイズを事前に決定し、それに応じて初期化できます。書き直す必要はありません。
JITが一方を他方にコンパイルしない理由は、削除がはるかに直感的な表記であるため、私には謎です。しかし、ご覧のとおり、他の方法に比べて効率が悪いため、慎重に使用する必要があります。ループ内では絶対に使用しないでください。