ジェイソンが言ったように、あなたのコードは次と同等です:
Enumerable.Range(0, 10).Where(n => n % 2 == 0);
ラムダは、すべての要素に対して行われる関数呼び出しに変換されることに注意してください。これはおそらくオーバーヘッドの最大の部分です。この正確なタスクでLINQが約3倍遅いことを示すテストを行いました(モノgmcsバージョン1.2.6.0)
ループ担当者の 10000000 の時間: 00:00:17.6852560
10000000 LINQ 担当者の時間: 00:00:59.0574430
ループ担当者の 1000000 の時間: 00:00:01.7671640
1000000 LINQ 担当者の時間: 00:00:05.8868350
編集: Gishu は VS2008 とフレームワーク v3.5 SP1 が与えることを報告します:
1000000 回のループ回数の時間: :00.3724585
1000000 LINQ 担当者の時間: :00.5119530
LINQ はそこで約 1.4 倍遅くなります。
for ループとリストを LINQ (および内部で使用する構造) と比較します。どちらの方法でも、結果を配列に変換します (LINQ が「怠惰」になるのを強制的に停止するために必要です)。両方のバージョンが繰り返されます:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
public class Evens
{
private static readonly int[] numbers = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
private static int MAX_REPS = 1000000;
public static void Main()
{
Stopwatch watch = new Stopwatch();
watch.Start();
for(int reps = 0; reps < MAX_REPS; reps++)
{
List<int> list = new List<int>(); // This could be optimized with a default size, but we'll skip that.
for(int i = 0; i < numbers.Length; i++)
{
int number = numbers[i];
if(number % 2 == 0)
list.Add(number);
}
int[] evensArray = list.ToArray();
}
watch.Stop();
Console.WriteLine("Time for {0} for loop reps: {1}", MAX_REPS, watch.Elapsed);
watch.Reset();
watch.Start();
for(int reps = 0; reps < MAX_REPS; reps++)
{
var evens = from num in numbers where num % 2 == 0 select num;
int[] evensArray = evens.ToArray();
}
watch.Stop();
Console.WriteLine("Time for {0} LINQ reps: {1}", MAX_REPS, watch.Elapsed);
}
}
同様のタスクでの過去のパフォーマンス テスト (例: LINQ vs Loop - A performance test ) は、これを裏付けています。