3

/編集: ループは遅くなりません。時間を正しくとれませんでした。ラスマンの答えを見てください。

やや長くて複雑な関数の 3 つのパラメーターをループしていますが、理解できない 2 つのことに気付きました。

  1. 関数は 1 つの構造体 (必要なフィールドは 1 つだけ) を返すだけですが、反復ごとに上書きします。
  2. プロファイラーはend、最も内側のステートメントにfor非常に長い時間がかかることを示しています。

次の例を考えてみましょう (これは簡単にベクトル化できることは承知していますが、呼び出す関数を理解している限り、ベクトル化できません)。

function stuff = doSomething( x, y, z )
    stuff.one = x+y+z;
    stuff.two = x-y-z;
end

関数の実行方法

n = 50;
i = 0;
currenttoc = 0;
output = zeros(n^3,4);
tic
for x = 1:n
    for y = 1:n
        for z = 1:n
            i = i + 1;
            output(i,1) = x;
            output(i,2) = y;
            output(i,3) = z;
            stuff = doSomething(x,y,z);
            output(i,4) = stuff.one;
            if mod(i,1e4) == 0 % only for demonstration, not in final script
                currenttoc = toc - currenttoc;
                fprintf(1,'time for last 10000 iterations: %f \n',currenttoc)
            end
        end
    end
end

どうすればこれをスピードアップできますか? すべての反復が前の反復よりも長くかかるのはなぜですか? これは恐ろしいプログラミングだと確信しています。申し訳ありません。

4

3 に答える 3

2

への呼び出しを に置き換えてをプロットするdoSomethingと、 への呼び出しが毎回ますます時間がかかることがわかります。output(i,4)=toc;diff(output(:,4))fprintf

if-clauseほぼ同じ時間をかけて、すべての反復へのリターンを削除します。

于 2013-02-25T23:01:03.163 に答える
1

doSomething構造体ではなく複数の出力変数を返すと、はるかに高速になります

function [out1,out2] = doSomething( x, y, z )
    out1 = x+y+z;
    out2 = x-y-z;
end

後続の反復ごとに遅くなるという事実は奇妙であり、説明はありませんが、少なくとも速度が向上することを願っています.

于 2013-02-25T23:07:25.527 に答える
1

そのため、if ステートメントを次のように置き換えると、問題は大幅に解消されます。

if mod(i,1e4) == 0 % only for demonstration, not in final script
    fprintf(1,'time for last 10000 iterations: %f \n',toc); tic;
end

toc の操作が問題を引き起こしている可能性があると思います

于 2013-02-25T23:08:38.467 に答える