6

純粋に実験として、MATLAB で並べ替え関数を作成し、MATLAB プロファイラーで実行しています。私が最も困惑しているのは、要素の交換に関するものです。

マトリックス内の2つの要素を交換する「公式の」方法が見つかりました

self.Data([i1, i2]) = self.Data([i2, i1])

4 行のコードで実行するよりもはるかに遅く実行されます。

e1 = self.Data(i1);
e2 = self.Data(i2);
self.Data(i1) = e2;
self.Data(i2) = e1;

2 番目の例にかかる合計時間は、最初の例の 1 行のコードの12 分の 1 です。

誰かが理由について説明してくれますか?

4

5 に答える 5

4

最初の (遅い) アプローチでは、RHS 値は行列であるため、MATLAB は 2 つの要素を格納する新しい行列を作成する際にパフォーマンスの低下を招くと思います。2 番目の (高速) アプローチでは、要素を直接操作することでこれを回避します。

MATLAB コードを改善する方法については、MathWorks の記事「パフォーマンスを改善するためのテクニック」を参照してください。

于 2009-02-02T05:31:17.963 に答える
2

最初の操作を実行するために行列の一時的なコピーが作成される可能性があるという点でザックは潜在的に正しいですが、これを回避しようとする MATLAB 内の内部最適化があると推測する危険があります。使用している MATLAB のバージョンの関数である可能性があります。バージョン 7.1.0.246 (数年前) で両方のケースを試しましたが、約 2 ~ 2.5 の速度差しか見られませんでした。

これは、いわゆる「ループ展開」による速度向上の例である可能性があります。ベクトル操作を行う場合、内部コード内のあるレベルで、スワップするインデックスをループする FOR ループが存在する可能性があります。2 番目の例のスカラー演算を実行することで、ループによるオーバーヘッドを回避できます。次の 2 つの (ややばかげた) 例に注意してください。

vec = [1 2 3 4];

%Example 1:
for i = 1:4,
  vec(i) = vec(i)+1;
end;

%Example 2:
vec(1) = vec(1)+1;
vec(2) = vec(2)+1;
vec(3) = vec(3)+1;
vec(4) = vec(4)+1;

確かに、次のような単純なベクトル演算を使用する方がはるかに簡単です。

vec = vec+1;

ただし、上記の例は説明のためのものです。各例を複数回繰り返して時間を計ると、例 2 は実際には例 1 よりもいくらか高速です。既知の数 (この例では 4 つだけ) の小さなループの場合、実際にはループを省略した方が効率的です。もちろん、この特定の例では、上記のベクトル演算が実際には最速です。

私は通常、次のルールに従います。いくつかの異なることを試して、特定の問題に対して最速のものを選択してください。

于 2009-02-02T15:25:01.070 に答える
2

あなたもできる:

tmp = self.Data(i1);
self.Data(i1) = self.Data(i2);
self.Data(i2) = tmp;
于 2009-02-02T14:41:21.127 に答える