2009-11-28 58 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"); 
    } 

希望这可以帮助别人!

相关问题