Производительность LINQ

1,00
р.
Есть массив целых чисел. Нужно подсчитать количество элементов больше пяти.
int[] numbers = { 1, 3, 5, 7, 3, 2, 5, 7 }
Вариант с циклом:
int count = 0 foreach (int n in numbers) { if (n > 5) { count++ } }
Вариант с LINQ:
int count = numbers.Count(n => n > 5)
Что выгодней с точки зрения производительности и насколько существенна разница?


Ответ
Предыдущий ответ не имеет никакого отношения к реальности. Хотелось бы примера с подтверждением наличия случая, когда LINQ быстрее обычного кода. Нужно понимать, что нет ничего бесплатного. Свои пять копеек стоит даже использование foreach вместо обычного for. Если необходимо писать некую библиотеку, с требованием к производительности, то надо быть очень осторожным при использовании LINQ. Другой вопрос, что как правило преимущества качества кода гораздо важнее некоторого падения производительности.
int count = 0 //int[] numbers = { 1, 3, 5, 7, 3, 2, 5, 7 } int N = 100000 int RUN_COUNT = 10000 Random r = new Random() int[] numbers = Enumerable.Range(1, N).Select((x) => r.Next()).ToArray()
DateTime started = DateTime.Now for (int i = 0 i < RUN_COUNT i++) { count = 0 //foreach (int n in numbers) for (int j = 0 j < numbers.Length j++ ) { if (numbers[j] > 5) //if (n > 5) { count++ } } }
DateTime end = DateTime.Now TimeSpan tspan = end - started
double iteration_time_simple = (double)tspan.TotalMilliseconds / 1000 //--------------------------------------------------------- started = DateTime.Now for (int i = 0 i < RUN_COUNT i++) { count = numbers.Count(n => n > 5) }
end = DateTime.Now tspan = end - started
double iteration_time_linq = (double)tspan.TotalMilliseconds / 1000
Console.WriteLine("linqimple: {0}", iteration_time_linq / iteration_time_simple) Console.WriteLine("simple time: {0} seconds", iteration_time_simple) Console.WriteLine("linq time: {0} seconds", iteration_time_linq)
На выходе получаем:
linqimple: 2.612 simple time: 7.8125 seconds linq time: 20.40625 seconds
То есть вариант с LINQ работает более, чем в 2.5 раза медленнее.
Мое резюме: использовать LINQ, но при необходимости с помощью профилировщика переписывать совсем неадекватные места если писать LINQ без ума, можно и разницу более чем в 10 раз получить и далее.