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 秒かかります。私は 2 日間にわたって何十回もテストを実行しました (その間に再起動を行いました)。
数値を 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;
}
これを説明するものは何ですか?