2009-11-28 6 views
6

次のテストプログラムのためにスクワットをしていないようです。これは私が小さなリストでテストしているからですか?AsParallelはどのように機能しますか?

static void Main(string[] args) 
{ 
    List<int> list = 0.UpTo(4); 

    Test(list.AsParallel()); 
    Test(list); 
} 

private static void Test(IEnumerable<int> input) 
{ 
    var timer = new Stopwatch(); 
    timer.Start(); 
    var size = input.Count(); 
    if (input.Where(IsOdd).Count() != size/2) 
     throw new Exception("Failed to count the odds"); 

    timer.Stop(); 
    Console.WriteLine("Tested " + size + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); 
} 

private static bool IsOdd(int n) 
{ 
    Thread.Sleep(1000); 
    return n%2 == 1; 
} 

どちらのバージョンも実行に4秒かかります。

+2

拡張メソッドであるUptoはどうやって取得しましたか? – thewpfguy

答えて

23

タスクパラレルライブラリは、という静的タイプを気にします。 TPLによって処理される操作については、IParallelEnumerable<T>である必要があります。 Testに電話すると、コレクションをIEnumerable<T>に戻してキャストしています。したがって、コンパイラは、.Whereの呼び出しを、TPLによって提供されるパラレルバージョンではなく、System.Linq.Enumerable.Where拡張メソッドに解決します。

1

Parallelは、あなたのものをThreadPoolに入れて動作します。また、コア数はいくつですか?単一のコアマシンで作業している場合でも、実行には約4秒かかります。私はあなたが期待想像通り

5

(この質問は、AsParallel(のためのGoogle検索ではかなり高いランク以来.NET4のための更新))

わずか数の変更はあなたの例では、動作するようになります。

変更List<int> list = 0.UpTo(4);

あなたがParallelQueryを取るシグネチャを持つ関数のオーバーロードを追加した場合あなたの例では、仕事とvar list = Enumerable.Range(0, 4);に...

private static void Test(ParallelQuery<int> input) 
    { 
     var timer = new Stopwatch(); 
     timer.Start(); 

     int size = input.Count(); 
     if (input.Where(IsOdd).Count() != size/2) 
     { 
      throw new Exception("Failed to count the odds"); 
     } 
     timer.Stop(); 

     Console.WriteLine("Tested " + size + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); 
    } 

代わりに、LINQの構文を使用することができます....

private static void Test(ParallelQuery<int> list) 
    { 
     var timer = Stopwatch.StartNew(); 

     if ((from n in list.AsParallel() 
      where IsOdd(n) 
      select n).Count() != (list.Count()/2)) 
     { 
      throw new Exception("Failed to count the odds"); 
     } 

     Console.WriteLine("Tested " + list.Count() + " numbers in " + timer.Elapsed.TotalSeconds + " seconds"); 
    } 

希望すると、誰かに役立ちます。

関連する問題