Нещодавно я почав використовувати 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 додасть вартість - чи є аналогічна вартість і для постачальника об'єктів? Якщо так, то чи відрізняється він, якщо ви використовуєте декларативний чи функціональний синтаксис?