我写了一些基本的示例代码来熟悉 PLINQ。
我遇到了一些奇怪的事情。我不知道这是我的代码中的错误还是我对 PLINQ 的理解中的错误。
MSDN 文档指出,添加 AsOrdered() 将保留调用顺序,但可能会降低性能。
我编写了一些单元测试,并注意到文档中所述对结果集的顺序的影响。但我已经看到了对性能的反作用。
这是我的两种方法:
public IEnumerable<int> ParallelCalculatePrimesUpTo(int maxValue)
{
return from number in Enumerable.Range(1, maxValue).AsParallel()
where IsPrime(number)
select number;
}
public IEnumerable<int> OrderedParallelCalculatePrimesUpTo(int maxValue)
{
return from number in Enumerable.Range(1, maxValue).AsParallel().AsOrdered()
where IsPrime(number)
select number;
}
还有我非常简单的基准
[TestMethod]
public void SimplisticBenchmark6()
{
var primeNumberCalculator = new PrimeNumberCalculator();
var startTime = DateTime.Now;
primeNumberCalculator.ParallelCalculatePrimesUpTo(10000000).ToList();
var totalTime = DateTime.Now - startTime;
Console.WriteLine(totalTime);
}
[TestMethod]
public void SimplisticBenchmark7()
{
var primeNumberCalculator = new PrimeNumberCalculator();
var startTime = DateTime.Now;
primeNumberCalculator.OrderedParallelCalculatePrimesUpTo(10000000).ToList();
var totalTime = DateTime.Now - startTime;
Console.WriteLine(totalTime);
}
无论我多久运行一次这个测试,有序版本都胜过无序版本。我在四核计算机上订购的速度快了大约 4 秒。我得到大约 18 秒的有序的和 22 秒的无序的。在两天的时间里,我已经运行了数十次测试(在这两天之间重新启动)。
如果我将数字 10 000 000 降低到 6 000 000,差异仍然存在,但不太明显,如果我将其降低到 3 000 000,则速度大致相同。
我尝试按执行顺序运行测试,结果是相同的。
这是在 PLINQ 查询中调用的 IsPrime 方法:
// uses inneficient trial division algorithm
private bool IsPrime(int number)
{
if (number == 1)
return false;
for (int divisor = 2; divisor <= Math.Sqrt(number); divisor++)
{
if (number % divisor == 0)
return false;
}
return true;
}
这是什么解释?