Как сказал Джейсон, ваш код эквивалентен:
Enumerable.Range(0, 10).Where(n => n % 2 == 0);
Примечание лямбда будет преобразован в вызов функции, которая делается для каждого элемента. Это, вероятно, самая большая часть накладных расходов. Я сделал тест, который показывает LINQ примерно в 3 раза медленнее (моно GMCS версия 1.2.6.0) на этой точной задачи
Time for 10000000 for loop reps: 00:00:17.6852560
Time for 10000000 LINQ reps: 00:00:59.0574430
Time for 1000000 for loop reps: 00:00:01.7671640
Time for 1000000 LINQ reps: 00:00:05.8868350
EDIT: Gishu сообщает, что VS2008 и рамки v3.5 SP1 дает:
Time for 1000000 loop reps: :00.3724585
Time for 1000000 LINQ reps: :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) подтверждает это.
Вы используете это на Mono? Вы уверены, что это сопоставимо с Microsoft IL? –
Mono использует MSIL, который также известен как CIL после стандартизации. –
Да, но это не значит, что два компилятора создают эквивалентный вывод. –