给定大量对象,以下各项之间是否存在性能差异?
集合包含:
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
给定大量对象,以下各项之间是否存在性能差异?
集合包含:
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Answers:
Contains()
是实例方法,其性能在很大程度上取决于集合本身。例如,Contains()
a List
是O(n),而Contains()
a HashSet
是O(1)。
Any()
是扩展方法,将简单地遍历集合,将委托应用于每个对象。因此,它的复杂度为O(n)。
Any()
但是更灵活,因为您可以传递一个委托。Contains()
只能接受一个对象。
Contains
也是一种针对的扩展方法IEnumerable<T>
(尽管某些集合也有自己的Contains
实例方法)。如您所说,Any
它比Contains
您可以传递给它一个自定义谓词更灵活,但由于它不需要为每个元素执行委托调用,因此它Contains
可能稍快一些。
All()
操作类似。
这取决于收藏。如果您有一个有序的集合,则Contains
可能会进行智能搜索(二进制,哈希,b树等),而使用`Any()则基本上是坚持枚举,直到找到它为止(假定LINQ-to-Objects) 。
还要注意,在您的示例中,Any()
正在使用==
运算符,该运算符将检查引用相等性,而Contains
将使用IEquatable<T>
或Equals()
方法,该运算符可能会被覆盖。
我想这取决于myCollection
决定如何Contains()
实现的is 的类型。例如,如果使用排序的二叉树,则搜索会更智能。同样,它也可以考虑元素的哈希值。 Any()
另一方面,将枚举整个集合,直到找到满足条件的第一个元素。如果对象具有更智能的搜索方法,则没有优化。
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)。
希望这会工作....