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