2009-11-28 79 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 2014-01-28 09:34:28

回答

23

Task Parallel Library關心序列的靜態類型。對於TPL要處理的操作,應該是IParallelEnumerable<T>。當您撥打Test時,您正在將收藏集重新制作回IEnumerable<T>。因此,編譯器會將.Where調用序列解析爲System.Linq.Enumerable.Where擴展方法,而不是TPL提供的並行版本。

1

As Parallel通過將你的東西放到ThreadPool中工作。另外,你有多少核心?如果您正在研發一臺運行4秒鐘的單核機器。

5

(更新爲.NET4因爲這個問題排名相當高的在谷歌搜索進行AsParallel())

短短几年的變化將讓你的榜樣工作,我想你的預期。

變化List<int> list = 0.UpTo(4);var list = Enumerable.Range(0, 4);

,如果你增加了一個功能,過載的需要ParallelQuery簽名你的榜樣會工作......

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"); 
    } 

希望這可以幫助別人!

相關問題