それはパフォーマンスだけでなく重要です。1番目と2番目のクエリの結果は等しくありません。並列処理を行い、元の順序を維持するためのソリューションがあります。を使用しAsParallel().AsOrdered()
ます。3番目のクエリはそれを示しています。
var SlowProjection = new Func<int, int>((input) => { Thread.Sleep(100); return input; });
var Measure = new Action<string, Func<List<int>>>((title, measure) =>
{
Stopwatch sw = Stopwatch.StartNew();
var result = measure();
sw.Stop();
Console.Write("{0} Time: {1}, Result: ", title, sw.ElapsedMilliseconds);
foreach (var entry in result) Console.Write(entry + " ");
});
Measure("Sequential", () => Enumerable.Range(0, 30)
.Select(SlowProjection).Where(x => x > 10).ToList());
Measure("Parallel", () => Enumerable.Range(0, 30).AsParallel()
.Select(SlowProjection).Where(x => x > 10).ToList());
Measure("Ordered", () => Enumerable.Range(0, 30).AsParallel().AsOrdered()
.Select(SlowProjection).Where(x => x > 10).ToList());
結果:
Sequential Time: 6699, Result: 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Parallel Time: 1462, Result: 12 16 22 25 29 14 17 21 24 11 15 18 23 26 13 19 20 27 28
Ordered Time: 1357, Result: 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
驚いたのですが、10回以上のテスト実行後も結果は一貫していました。少し調べてみたところ、.Net4.0では「バグ」であることが判明しました。4.5では、AsParallel()はAsParallel()。AsOrdered()より遅くありません。
参照はここにあります:
http://msdn.microsoft.com/en-us/library/dd460677(v=vs.110).aspx