Ответ 1
Напишите самый четкий код, который вы можете, а затем сравнительный анализ и профиль, чтобы обнаружить любые проблемы с производительностью. Если у вас есть проблемы с производительностью, вы можете поэкспериментировать с другим кодом, чтобы выяснить, быстрее или нет это (все время измеряя как можно более реалистичные данные), а затем вынести решение о том, стоит ли повысить производительность удар.
Прямой подход foreach
во многих случаях будет быстрее LINQ. Например, рассмотрим:
var query = from element in list
where element.X > 2
where element.Y < 2
select element.X + element.Y;
foreach (var value in query)
{
Console.WriteLine(value);
}
Теперь есть два предложения where
и предложение select
, поэтому каждый конечный элемент должен пройти через три итератора. (Очевидно, что два предложения, которые могут быть объединены в этом случае, но я делаю общий вывод.)
Теперь сравните его с прямым кодом:
foreach (var element in list)
{
if (element.X > 2 && element.Y < 2)
{
Console.WriteLine(element.X + element.Y);
}
}
Это будет работать быстрее, потому что у него меньше обручей. Скорее всего, вывод на консоль будет затмевать стоимость итератора, и я бы предпочел бы запрос LINQ.
РЕДАКТИРОВАТЬ: Чтобы ответить на петли "вложенные foreach"... обычно те, которые представлены с помощью SelectMany
или второго предложения from
:
var query = from item in firstSequence
from nestedItem in item.NestedItems
select item.BaseCount + nestedItem.NestedCount;
Здесь мы добавляем только один дополнительный итератор, потому что мы уже будем использовать дополнительный итератор для каждого элемента в первой последовательности из-за вложенного цикла foreach
. Там все еще немного накладных расходов, в том числе накладные расходы на выполнение проекции в делегате вместо "встроенного" (что-то, о чем я не упоминал ранее), но он все равно не будет сильно отличаться от производительности вложенного foreach.
Это не значит, что вы не можете стрелять в ногу с помощью LINQ, конечно. Вы можете писать безупречно неэффективные запросы, если сначала не занимаетесь своим мозгом, но это далеко не уникально для LINQ...