Учитывая огромную коллекцию объектов, существует ли разница в производительности между следующими?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Учитывая огромную коллекцию объектов, существует ли разница в производительности между следующими?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Содержит() - метод экземпляра, и его производительность во многом зависит от самой коллекции. Например, Contains() в списке - O (n), а Contains() в HashSet - O (1).
Any() - это метод расширения и будет просто проходить через коллекцию, применяя делегат к каждому объекту. Поэтому он имеет сложность O (n).
Любая() более гибкая, так как вы можете передать делегат. Contains() может принимать только объект.
Это зависит от коллекции. Если у вас есть упорядоченная коллекция, то Contains может выполнять интеллектуальный поиск (двоичный, хэш, b-дерево и т.д.), А с Any() вы в основном застреваете с перечислением, пока не найдете его (при условии, что LINQ to Objects)
Также обратите внимание, что в вашем примере Any() использует оператор "==", который будет проверять ссылочное равенство, в то время как Contains будет использовать метод IEquitable или Equals(), который может быть переопределен.
Я полагаю, что это будет зависеть от типа myCollection
, который диктует реализацию Contains()
. Например, если отсортированное двоичное дерево, оно может искать более умное. Также он может принимать во внимание элемент хэш. 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).
Надеюсь, это будет работать....