[英]How exactly does AsParallel work?
以下测试程序似乎没有下蹲。 这是因为我正在测试一个小清单吗?
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提供的并行版本。
(更新.NET4,因为这个问题在Google搜索AsParallel()时排名很高)
只需进行一些更改,您的示例就可以像我想象的那样工作。
Change List<int> list = 0.UpTo(4);
to 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");
}
希望这有助于某人!
正如Parallel通过将您的东西放入ThreadPool而工作。 另外,你有多少个核心? 如果你正在使用一台仍需要大约4秒才能运行的单核机器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.