2013-08-28 9 views
5

ループの文で浪費される時間のパフォーマンスは、ループ自体よりもはるかに高いため、この観察はそれほど重要ではありません。しかし、とにかく、私が検索して、これについての話題を見つけることができなかったので、私はそれを共有します。私はいつも、私がループする配列を事前割り付けし、それをループするという印象は、直接ループするよりもうまくいくと思っていました。ループ文のパフォーマンスとループ文の事前割り振り

disp('Pure for with column on statement:') 
tic 
for k=1:N 
end 
toc 

disp('Pure for with column declared before statement:') 
tic 
m=1:N; 
for k=m 
end 
toc 

しかし、私が得た結果は以下のとおりです:

Pure for with column on statement: 
Elapsed time is 0.003309 seconds. 
Pure for with column declared before statement: 
Elapsed time is 0.208744 seconds. 

は地獄がそれをなぜコードは、この2つのFORS間の効率を比較するだろうか?あらかじめ割り当てるのは速いはずですか?実際に

、MATLAB help forは言う:インデックスベクトルが作成されることはありませんので、大腸式はFOR文で を表示されたときに

長いループは、より多くのメモリ効率的です。そのことを、高速であるので、それは、ベクトルを割り当て、していないため

ので、for文で私の期待列式と矛盾することは、より良いです。

私は、私もそれがより速くなると思うだろう他の機会テストするには、次のスクリプトを作っ:

% For comparison: 
N=1000000; 

disp('Pure for loop on cell declared on statement:') 
tic 
for k=repmat({1},1,N) 
end 
toc 

disp('Pure for loop on cell declared before statement:') 
tic 
mcell=repmat({1},1,N); 
for k=mcell 
end 
toc 

disp('Pure for loop calculating length on statement:') 
tic 
for k=1:length(mcell) 
end 
toc 

disp('Pure for loop calculating length before statement:') 
tic 
lMcell = length(mcell); 
for k=1:lMcell 
end 
toc 

disp('Pure while loop using le:') 
% While comparison: 
tic 
k=1; 
while (k<=N) 
    k=k+1; 
end 
toc 

disp('Pure while loop using lt+1:') 
% While comparison: 
tic 
k=1; 
while (k<N+1) 
    k=k+1; 
end 
toc 


disp('Pure while loop using lt+1 pre allocated:') 
tic 
k=1; 
myComp = N+1; 
while (k<myComp) 
    k=k+1; 
end 
toc 

をそしてタイミングは以下のとおりです。

Pure for loop on cell declared on statement: 
Elapsed time is 0.259250 seconds. 
Pure for loop on cell declared before statement: 
Elapsed time is 0.260368 seconds. 
Pure for loop calculating length on statement: 
Elapsed time is 0.012132 seconds. 
Pure for loop calculating length before statement: 
Elapsed time is 0.003027 seconds. 
Pure while loop using le: 
Elapsed time is 0.005679 seconds. 
Pure while loop using lt+1: 
Elapsed time is 0.006433 seconds. 
Pure while loop using lt+1 pre allocated: 
Elapsed time is 0.005664 seconds. 

結論:

  • コンマ文のループだけで少しのパフォーマンスを得ることはできますが、それはthに費やされた時間と比較すると無視できる程度ですe forループ。
  • セルの場合、その違いはごくわずかです。
  • ループを実行する前に長さを事前に割り当てる方がよいです。
  • whileは、前に説明したようにベクトルを事前割り付けしない場合と同じ効率を持っています。
  • 予想通り、while文の前に固定式を計算する方が良いでしょう。

しかし、私が答えることができない質問は、細胞はどうですか、なぜ時間差がないのですか?オーバーヘッドは、観測されたオーバーヘッドよりはるかに小さいでしょうか?または、それは倍精度としての基本型ではないので、セルを割り当てる必要がありますか?

このトピックに関する他のトリックを知っていれば、追加してください。

ただ、@ Maglaの答えに言ったようにfeature('accel','off')を回すの結果を表示するタイミングを追加する

。予想通り

Pure for with column on statement: 
Elapsed time is 0.181592 seconds. 
Pure for with column declared before statement: 
Elapsed time is 0.180011 seconds. 
Pure for loop on cell declared on statement: 
Elapsed time is 0.242995 seconds. 
Pure for loop on cell declared before statement: 
Elapsed time is 0.228705 seconds. 
Pure for loop calculating length on statement: 
Elapsed time is 0.178931 seconds. 
Pure for loop calculating length before statement: 
Elapsed time is 0.178486 seconds. 
Pure while loop using le: 
Elapsed time is 1.138081 seconds. 
Pure while loop using lt+1: 
Elapsed time is 1.241420 seconds. 
Pure while loop using lt+1 pre allocated: 
Elapsed time is 1.162546 seconds. 

結果が今面積...

答えて

3

この知見は、事前に割り当てるかどうかとは関係ありません:それは、MATLABは、複数のコアで物事を計算するために使用可能かどうかであることを扱っています。 forステートメント内にコロン演算子を挿入すると、matlabはいくつかのコア(マルチスレッド)を使用するように指示します。

feature('accel','off')で1つのコアにのみmatlabを設定すると、doublesでの観測された差は消えます。 cellsに関しては、matlabはマルチスレッディングを使用していないので、違いはありません(accelのステータスに関係なく)。

ループは、コロンを使用する場合、およびコロンを使用する場合のみマルチスレッド化されます。

  • for k = randperm(N)
  • for k = linspace(1,N,N)

しかしfor k = 1:0.9999:Nマルチスレッドである:同様の長さの以下のベクターは、いくつかのコアを係合しません。

これについては、matlab's support pageの説明があります。マルチコア処理は、「関数によって実行されるアルゴリズムの操作が、同時に実行できるセクションに簡単に分割される」ときに実行できることを示しています。コロン演算子を使用すると、Matlabはforがパーティション化できることを認識します。

+0

今は意味があります...ありがとうございます! – Werner

+3

Matlabは 'for'ループをマルチスレッドすることは安全であることを事前に知ることができましたか?私の理解では、Matlabは 'fft'、' eig'、 'svd'、' sort'などのマルチスレッド関数をネイティブに扱いますが、ループ上でマルチスレッドを行うには並列処理ツールボックスと 'parfor'構造が必要です...この機能について説明している公式文書はありますか? –

+0

@ Colin T Bowers - 編集をご覧ください。私の理解に。 'for'ブロックの内容をマルチスレッドするために' parfor'関数が使われます。ここでは、評価されるのは単なる反復関数呼び出しです。 – marsei