LINQ и производительность
Вопрос
Насколько LINQ дорог и когда вы от него отказываетесь?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Отложенное выполнение и риск многократного перечисления
Аллокации: итераторы, делегаты, замыкания на захваченные переменные
В горячих циклах можно заменить на for/foreach по массиву или Span
Методы вроде Count() и Any() оптимизированы для ICollection
В .NET 7-9 сильно ускорены Min, Max, Sum, Order (векторизация)
Сначала профилирование (BenchmarkDotNet), читаемость важнее микроскопической выгоды
Что могут спросить следом
- Что быстрее:
list.Countилиlist.Count()? - Почему
Any()лучшеCount() > 0?
Разбор
LINQ платит за удобство: на каждый оператор создаётся объект-итератор, лямбда превращается в делегат, а захват переменных добавляет объект-замыкание. Каждый элемент проходит через вызов делегата. В обычном бизнес-коде это незаметно, а в горячем цикле, который вызывается миллионы раз, заметно.
Вторая проблема логическая: отложенное выполнение. Если передать запрос дальше и перечислить его несколько раз, тяжёлая работа повторится. Я материализую результат через ToList там, где он нужен несколько раз.
Много что уже оптимизировано: Count() у ICollection берёт свойство Count, Any() останавливается на первом элементе, а в последних версиях .NET Sum, Min, Max по массивам векторизованы. Поэтому я не переписываю LINQ на циклы заранее, а сначала меряю BenchmarkDotNet или профилировщиком и заменяю только горячие места на for по массиву или Span.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.