Нещодавно я почав використовувати LINQ зовсім небагато, і я насправді не бачив жодної згадки про складність виконання жодного з методів LINQ. Очевидно, що тут грає багато факторів, тому давайте обмежимось обговоренням простого IEnumerableпостачальника LINQ-до-об'єктів. Далі припустимо, що будь-який Funcпереданий як селектор / мутатор / тощо є дешевою операцією O (1).
Видається очевидним , що всі операції за один прохід ( Select, Where, Count, Take/Skip, Any/Allі т.д.) буде O (п), так як вони тільки повинні пройти послідовність один раз; хоча навіть це підлягає ліні.
Все складніше для складніших операцій; безліч подібних операторів ( Union, Distinct, Exceptі т.д.) роботи з використанням GetHashCodeза замовчуванням (AFAIK), так що здається розумним припустити , що вони використовують хеш-таблицю всередині, що робить ці операції O (п), а також , в цілому. А як щодо версій, які використовують IEqualityComparer?
OrderByзнадобиться сортування, тому, швидше за все, ми дивимось на O (n log n). Що робити, якщо це вже відсортовано? Як щодо того, якщо я скажу OrderBy().ThenBy()і надаю однаковий ключ для обох?
Я міг бачити GroupBy(і Join), використовуючи або сортування, або хешування. Що це таке?
Containsбуде O (n) на a List, але O (1) на a HashSet- чи LINQ перевіряє базовий контейнер, щоб побачити, чи може він прискорити роботу?
І справжнє питання - досі я вважаю, що операції виконуються. Однак чи можу я взяти участь у цьому? Наприклад, контейнери STL чітко вказують на складність кожної операції. Чи є подібні гарантії на продуктивність LINQ у специфікації бібліотеки .NET?
Більше запитання (у відповідь на коментарі): Я
не дуже думав про накладні витрати, але я не очікував, що там буде дуже багато простого Linq-to-Objects. Публікація CodingHorror говорить про Linq-to-SQL, де я можу зрозуміти, що аналіз запиту і створення SQL додасть вартість - чи є аналогічна вартість і для постачальника об'єктів? Якщо так, то чи відрізняється він, якщо ви використовуєте декларативний чи функціональний синтаксис?