AsParallel的工作原理是什么?
问题描述:
它似乎没有做下面的测试程序的深蹲。这是因为我正在测试一个小列表吗?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秒钟才能运行。
答
Task Parallel Library关心序列的静态类型。对于TPL要处理的操作,应该是IParallelEnumerable<T>
。当您拨打Test
时,您正在将收藏集重新制作回IEnumerable<T>
。因此,编译器会将.Where
调用序列解析为System.Linq.Enumerable.Where
扩展方法,而不是TPL提供的并行版本。
答
As Parallel通过将你的东西放到ThreadPool中工作。另外,你有多少核心?如果您正在研发一台运行4秒钟的单核机器。
答
(更新为.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");
}
希望这可以帮助别人!
你是如何获得Upto的扩展方法? – thewpfguy 2014-01-28 09:34:28