我最近开始大量使用 LINQ,并且我还没有真正看到任何 LINQ 方法的运行时复杂性。显然,这里有许多因素在起作用,因此让我们将讨论限制在简单的 IEnumerable
LINQ-to-Objects 提供程序上。此外,让我们假设作为选择器/变异器等传入的任何 Func
都是廉价的 O (1)操作。
显而易见,所有的单遍操作(Select
、 Where
、 Count
、 Take/Skip
、 Any/All
等)都将是 O (n) ,因为它们只需要遍历序列一次; 尽管这也会受到惰性的影响。
对于更复杂的操作来说,情况更加模糊; 类似集合的操作符(Union
、 Distinct
、 Except
等)默认使用 GetHashCode
工作(afaik) ,因此假设它们在内部使用哈希表似乎是合理的,通常这些操作也是 O (n)。使用 IEqualityComparer
的版本怎么样?
OrderBy
需要排序,所以很可能是 O (n log n)。如果已经解决了呢?如果我说 OrderBy().ThenBy()
并为两者提供相同的密钥怎么样?
我可以看到使用排序或散列的 GroupBy
(和 Join
)。是哪个?
Contains
在 List
上是 O (n) ,但在 HashSet
上是 O (1)—— LINQ 是否检查底层容器,看看它是否能加快速度?
真正的问题是,到目前为止,我一直相信这些操作是可行的。不过,我能指望这一点吗?例如,STL 容器清楚地指定了每个操作的复杂性。中的 LINQ 性能是否有类似的保证。NET 库规范? ?
更多问题(回应评论) :
没有真正考虑过开销,但是我并不期望有很多简单的 Linq-to-Objects。CodingHorror 这篇文章讨论的是 Linq-to-SQL,在这里我可以理解解析查询和使用 SQL 会增加成本——对象提供程序也有类似的成本吗?如果是这样,那么使用声明式语法或函数式语法是否有所不同?