2016-10-23 9 views
3

私が正しくすることができますLINQクエリで質問

(のように:コンパイラは文句はありません)このよう.AsParallel()を呼び出します。LINQクエリで.AsParallel()を呼び出すためにどこ

(from l in list.AsParallel() where <some_clause> select l).ToList(); 

またはこのような:まさに違いは何であるか

(from l in list where <some_clause> select l).AsParallel().ToList(); 

?私はほとんど常に、私はそれが進むべき道だと思ったので、使用される最初の方法を見てきましたofficial documentationから判断

を試してみた何


今日、私は自分自身でベンチマークをいくつか実行しようとしましたが、その結果は驚くべきものでした。

var list = new List<int>(); 
var rand = new Random(); 
for (int i = 0; i < 100000; i++) 
    list.Add(rand.Next()); 

var treshold= 1497234; 

var sw = new Stopwatch(); 

sw.Restart(); 
var result = (from l in list.AsParallel() where l > treshold select l).ToList(); 
sw.Stop(); 

Console.WriteLine($"call .AsParallel() before: {sw.ElapsedMilliseconds}"); 

sw.Restart(); 
result = (from l in list where l > treshold select l).AsParallel().ToList(); 
sw.Stop(); 

Console.WriteLine($"call .AsParallel() after: {sw.ElapsedMilliseconds}"); 

出力

コール.AsParallel()の前に:49
コール.AsParallel()の後:4だから、

、ここで私が実行したコードです明らかに、ドキュメンテーションの記載にもかかわらず、第2の方法ははるかに高速です。ここで何が起こっているのですか?

+0

あなたのマシンはシングルコアまたはマルチコアですか? –

+0

@viveknunaマルチコア – Mahatma

+0

これはいつも別の結果を与えるでしょう –

答えて

5

一般に、AsParallelを使用するのは、並行処理による節約が並行処理のオーバーヘッドよりも重要かどうかを判断することです。

あなたのような条件を評価するのが簡単な場合、複数の並列ストリームを作成し、結果を最終的に収集するオーバーヘッドは、並行して比較を実行する利点を大きく上回ります。

条件が計算上激しい場合、複数のWhereの計算を並行して実行するメリットと比較して、オーバーヘッドが小さくなっているため、AsParallelコールを早く早くすると、かなり高速になります。

計算上困難な状況の例として、数値が素数かどうかを判断する方法を考えてみましょう。マルチコアCPU上でこれを並列に実行すると、並列化されていない実装よりも大幅に改善されます。

+0

あなたの答えをありがとうが、私はまだ2つの呼び出しの違いを理解していません。 2番目の方法(クエリの終わりに)で.AsParallel()を呼び出すと、実際には何も並列化されていないことを意味しますか? – Mahatma

+1

@マハトマはい、それまでに作業はすでにシーケンシャルモードで行われています。すべてのLINQのニーズは、並列ストリームの結果を単一のリストに集めることです。 – dasblinkenlight

+0

私は今、大変ありがとうございます。 – Mahatma

関連する問題