LINQ Ring:任何()vs Contains()用于巨大的集合

时间:2010-12-14 23:09:35

标签: c# linq performance benchmarking

鉴于大量对象,以下是否有性能差异?

Collection.Contains

myCollection.Contains(myElement)

Enumerable.Any

myCollection.Any(currentElement => currentElement == myElement)

4 个答案:

答案 0 :(得分:121)

Contains()是一种实例方法,其性能在很大程度上取决于集合本身。例如,List上的Contains()是O(n),而HashSet上的Contains()是O(1)。

Any()是一个扩展方法,只需遍历集合,在每个对象上应用委托。因此它具有O(n)的复杂性。

Any()更灵活,因为您可以传递委托。 Contains()只能接受一个对象。

答案 1 :(得分:12)

这取决于收藏品。如果你有一个有序的集合,那么Contains可以做一个智能搜索(二进制,哈希,b树等),而使用Any()你基本上坚持枚举,直到你找到它(假设LINQ to Objects)

另请注意,在您的示例中,Any()使用“==”运算符来检查引用相等性,而Contains将使用IEquitable或可能被覆盖的Equals()方法。

答案 2 :(得分:4)

我认为这取决于myCollection的类型,它决定了Contains()的实施方式。例如,如果是排序的二叉树,它可以更智能地搜索。此外,它可能会考虑元素的哈希值。另一方面,Any()将枚举整个集合,直到找到满足条件的第一个元素。如果对象具有更智能的搜索方法,则没有优化。

答案 3 :(得分:0)

Contains()也是一种扩展方法,如果以正确的方式使用它,则可以快速运行。 例如:

var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();

这将给出查询

SELECT Id FROM Projects INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item

而另一方面,Any()总是迭代O(n)。

希望这可以。...