8

少し前に大学で matlab を使い始めたとき、スーパーバイザーは不要な for ループを見たら私を殺しました (彼はそれを交換するkronか、可能な限り任意のタイプのインデックス操作を要求しました)。後で、単純なループの代わりに黒魔術を行うための最も暗いmatlabコーディング方法を探して、matlabでのループを可能な限り回避しようとしていました。

そして、ある日cellfun、黒魔術を非常に単純にする を発見しました。セルとコンボを操作する多くのループを変更できましたが、ある日、 cellfun に関するcellfun1 つの投稿を見て、継承された matlab の知識が正しいかどうか疑問に思いました。matlab のループは常に 1 つの組み込みのコンパイル済み関数よりも遅くなるということ、これは私が非常に信頼していたことでした。私は自分の実装の 1 つでそれをテストしましたが、実際、for ループの方が高速です。私は、OMG、あいまいなコードを何日も無駄にしたことは、ハハハのようでした。その日以来、私は matlab コードを最適化しようとするのをやめました。通常、それはケースごとに異なります。

今日、私はこの回答を見ました。これは、可能な限り多くのmatlabループを回避するための私の努力を思い出しました(パフォーマンスのために作者が回避する意志があるかどうかはわかりませんが、とにかく、このすべてのmatlabループパフォーマンスのことを思い出させました)。そして、1 つの質問が頭に浮かびました。cellfun は for ループより優れているのでしょうか? それはいつ本当ですか?

4

4 に答える 4

4

自分でテストした結果に1つの回答を追加しますが、人々が知識を提供してくれるとうれしいです.これは私が行った簡単なテストです.

1000 および 1000 ループのセル サイズで次の条件をテストしました (合計時間の結果。結果に少し変動があるため、おそらく 1000 回以上実行する必要がありますが、とにかく、これはそうではありません科学論文):

  • 基本操作(和)
    • 単純な for ループ: 0.2663 秒
    • セルファン: 9.4612 秒
  • 文字列操作 (strcmp)
    • 単純な for ループ: 1.3124 秒
    • セルファン: 11.8099 秒
  • ビルトイン (isempty)
  • 不均一 (正規表現)
    • 単純な for ループ: 24.2157 秒
    • cellfun (文字列入力): 44.0424 秒

したがって、匿名関数呼び出しを伴う cellfun は単純な for ループよりも遅いようですが、組み込みの matlab メソッドを使用する場合は、cellfun で実行し、文字列引用符で使用します。これは必ずしもすべてのケースに当てはまるわけではありませんが、少なくともテストされた関数には当てはまります。

実装されたテスト コード (私は最適化のスペシャリストではありません。間違ったことをした場合に備えて、ここにコードを示します):

function ...
  [loop_timeAdd,cellfun_timeAdd,...
  loop_timeStr,cellfun_timeStr,...
  loop_timeBuiltIn,cellfun_timeBuiltInStrInput,...
  cellfun_timeBuiltyInFcnHandle,...
  loop_timeNonUniform,cellfun_timeNonUniform] ...
  = test_cellfun(nTimes,nCells)

myCell = repmat({0},1,nCells);
output = zeros(1,nCells);

% Basic operation
tic;
for k=1:nTimes
  for m=1:nCells
    output(m) = myCell{m} + 1;
  end
end
loop_timeAdd=toc;

tic;
for k=1:nTimes
  output = cellfun(@(in) in+1,myCell);
end
cellfun_timeAdd=toc;

% String operation
myCell = repmat({'matchStr'},1,nCells); % Add str that matches
myCell(1:2:end) = {'dontMatchStr'}; % Add another str that doesnt match
output = zeros(1,nCells);

tic;
for k=1:nTimes
  for m=1:nCells
    output(m) = strcmp(myCell{m},'matchStr');
  end
end
loop_timeStr=toc;

tic;
for k=1:nTimes
  output = cellfun(@(in) strcmp(in,'matchStr'),myCell);
end
cellfun_timeStr=toc;

% Builtin function (isempty)
myCell = cell(1,nCells); % Empty
myCell(1:2:end) = {0}; % not empty
output = zeros(1,nCells);

tic;
for k=1:nTimes
  for m=1:nCells
    output(m) = isempty(myCell{m});
  end
end
loop_timeBuiltIn=toc;

tic;
for k=1:nTimes
  output = cellfun(@isempty,myCell);
end
cellfun_timeBuiltyInFcnHandle=toc;

tic;
for k=1:nTimes
  output = cellfun('isempty',myCell);
end
cellfun_timeBuiltInStrInput=toc;

% Builtin function (isempty)
myCell = repmat({'John'},1,nCells);
myCell(1:2:end) = {'Doe'};
output = cell(1,nCells);

tic;
for k=1:nTimes
  for m=1:nCells
    output{m} = regexp(myCell{m},'John','match');
  end
end
loop_timeNonUniform=toc;

tic;
for k=1:nTimes
  output = cellfun(@(in) regexp(in,'John','match'),myCell,...
    'UniformOutput',false);
end
cellfun_timeNonUniform=toc;
于 2013-08-17T00:47:53.257 に答える