Parallel LINQ (PLINQ)
Parallel LINQ (PLINQ) は、統合言語クエリ (LINQ) パターンの並列実装です。 PLINQ は、LINQ 標準クエリ演算子の完全なセットを System.Linq 名前空間の拡張メソッドとして実装し、並列操作用の追加演算子も備えています。 PLINQ は、LINQ 構文の単純さと読みやすさに加え、並列プログラミングのパワーを兼ね備えています。
やってみよう。
ノーマル LINQ
Program.cs
var source1 = Enumerable.Range(1, 1000000);
var source2 = Enumerable.Range(1, 1000000);
var ret = from r1 in source1
join r2 in source2
on r1 equals r2
where r1 % 2 == 0 && r2 % 3 == 0
orderby r1
select r1;
Console.WriteLine($"{ret.Count()} {ret.First()} {ret.Last()}");
// 166666 6 999996
パラレル LINQ
Program.cs
var source1 = Enumerable.Range(1, 1000000);
var source2 = Enumerable.Range(1, 1000000);
var ret = from r1 in source1.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism).WithDegreeOfParallelism(4)
join r2 in source2.AsParallel()
on r1 equals r2
where r1 % 2 == 0 && r2 % 3 == 0
orderby r1
select r1;
Console.WriteLine($"{ret.Count()} {ret.First()} {ret.Last()}");
// 166666 6 999996
・AsParallel()
で並列化
・WithExecutionMode(ParallelExecutionMode.ForceParallelism)
で強制する
・WithDegreeOfParallelism(4)
で並列数を4にする
ノーマル LINQ (改)
where r1 % 2 == 0 && r2 % 3 == 0
だとJOIN後なので効率悪いのでは?
Program.cs
var source1 = Enumerable.Range(1, 1000000);
var source2 = Enumerable.Range(1, 1000000);
var ret = from r1 in (from r3 in source1
where r3 % 2 == 0
select r3)
join r2 in (from r4 in source2
where r4 % 3 == 0
select r4)
on r1 equals r2
orderby r1
select r1;
Console.WriteLine($"{ret.Count()} {ret.First()} {ret.Last()}");
// 166666 6 999996
パラレル LINQ (改)
同上
Program.cs
var source1 = Enumerable.Range(1, 1000000);
var source2 = Enumerable.Range(1, 1000000);
var ret = from r1 in (from r3 in source1.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism).WithDegreeOfParallelism(4)
where r3 % 2 == 0
select r3)
join r2 in (from r4 in source2.AsParallel()
where r4 % 3 == 0
select r4)
on r1 equals r2
orderby r1
select r1;
Console.WriteLine($"{ret.Count()} {ret.First()} {ret.Last()}");
// 166666 6 999996
性能比較
50回試行の平均
種類 | ミリ秒 |
---|---|
ノーマル LINQ | 906.2 |
パラレル LINQ (並列数4) | 190.5 |
ノーマル LINQ (改) | 337.8 |
パラレル LINQ (改) (並列数4) | 94.6 |