Учитывая огромную коллекцию объектов, есть ли разница в производительности между следующими?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Учитывая огромную коллекцию объектов, есть ли разница в производительности между следующими?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Ответы:
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()
будет реализовано. Например, в отсортированном двоичном дереве можно было бы искать более умный поиск. Также может учитываться хэш элемента. 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).
Надеюсь, это сработает ....