LINQ Ring: Any() vs Содержит() для огромных коллекций

Учитывая огромную коллекцию объектов, существует ли разница в производительности между следующими?

Collection.Contains:

myCollection.Contains(myElement)

Enumerable.Any:

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

Ответ 1

Содержит() - метод экземпляра, и его производительность во многом зависит от самой коллекции. Например, Contains() в списке - O (n), а Contains() в HashSet - O (1).

Any() - это метод расширения и будет просто проходить через коллекцию, применяя делегат к каждому объекту. Поэтому он имеет сложность O (n).

Любая() более гибкая, так как вы можете передать делегат. Contains() может принимать только объект.

Ответ 2

Это зависит от коллекции. Если у вас есть упорядоченная коллекция, то Contains может выполнять интеллектуальный поиск (двоичный, хэш, b-дерево и т.д.), А с Any() вы в основном застреваете с перечислением, пока не найдете его (при условии, что LINQ to Objects)

Также обратите внимание, что в вашем примере Any() использует оператор "==", который будет проверять ссылочное равенство, в то время как Contains будет использовать метод IEquitable или Equals(), который может быть переопределен.

Ответ 3

Я полагаю, что это будет зависеть от типа myCollection, который диктует реализацию Contains(). Например, если отсортированное двоичное дерево, оно может искать более умное. Также он может принимать во внимание элемент хэш. Any(), с другой стороны, будет перечисляться через коллекцию до тех пор, пока не будет найден первый элемент, который удовлетворяет условию. Оптимизаций нет, если у объекта был более интеллектуальный метод поиска.

Ответ 4

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).

Надеюсь, это будет работать....