2016-12-22 4 views
0

私はfor-loopで一連のhttp-sitesに接続するASP MVCコントローラを持っています。同様に:ASP.NET C#Parallel.ForEachパフォーマンスゲイン

foreach(string provider in providers){ 
    // get data from asomehttp URL 
} 

これは実行するのに約4秒かかり...

私が試してみた:

Parallel.ForEach(providers, (provider) => { 
    // get data from some http URL 
}); 

を、私は全くのパフォーマンスゲインを見ません!

これはなぜですか?

+1

ループ内のコードにも依存する可能性があります。 –

+0

おそらくボトルネックは検索ではなく、ポスト処理であるか、または単一のコアしかなく、コンテキスト切り替えのコストが重要ですあらゆる利益。さて、IOバインドされた作業は、非同期、待機中、およびTask.WhenAllと並列化する必要があります。特に競合するWebアプリケーションで。 – StuartLC

+1

それぞれのコード行にどのようなパフォーマンスが見られますか? 1つのサイトが時間の90%を取っている可能性がありますので、ほとんど違いはありません。各サイトの所要時間を確認できるようにタイマーログを追加することもできますが、それらを同時に実行する利点があります。 – Theo

答えて

2

ソースコレクションはパーティション化され、作業はシステム環境に基づいて複数のスレッドでスケジュールされます。システム上のプロセッサーが多いほど、並列メソッドが高速に実行されます。いくつかのソースコレクションでは、ソースのサイズに応じて、実行される作業の種類によってシーケンシャルループが速くなる場合があります。パフォーマンスの詳細については、Potential Pitfalls in Data and Task Parallelismを参照してください。 Do Not Assumeそのパラレルは常に高速です パラレルループは、連続する同等のループよりも遅く実行されることがあります。経験則の基本は、反復回数が少なく、高速なユーザー代理人を持つ並列ループは、スピードアップがあまりないということです。

ループを含むすべてのコードを並列化する場合、重要な目標の1つは、並列処理のオーバーヘッドがパフォーマンス上の利点を無効にするポイントまで並列化することなく、可能な限りプロセッサを利用することです。この特定のexampleでは、内部ループで実行される作業があまりないため、外部ループのみが並列化されます。少量の作業と望ましくないキャッシュ効果を組み合わせると、ネストされた並列ループでパフォーマンスが低下する可能性があります。したがって、ほとんどのシステムで並行処理の利点を最大限に活用するには、外部ループのみを並列化することが最善の方法です。

質問に答えるには、ソースのサイズと実行される作業の種類によって異なります。

関連する問題