113 votes

Anneau LINQ : Any() vs Contains() pour les grandes collections

Étant donné une énorme collection d'objets, y a-t-il une différence de performance entre les éléments suivants ?

Collection.Contient :

myCollection.Contains(myElement)

Enumerable.Any :

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

7 votes

Une collection de 10'000.000 d'int's. Le gagnant est celui qui contient 300%. mais il est bon de considérer les variances mentionnées ci-dessous.

1 votes

Cela semble montrer un contraste frappant entre les deux : thedailywtf.com/Articles/State-of-the-UNION.aspx

153voto

Etienne de Martel Points 16020

Contains() est une méthode d'instance, et ses performances dépendent largement de la collection elle-même. Par exemple, Contains() sur un List est O(n), tandis que Contains() sur un HashSet est O(1).

Any() est une méthode d'extension, et va simplement parcourir la collection, en appliquant le délégué sur chaque objet. Elle a donc une complexité de O(n).

Any() est cependant plus flexible puisque vous pouvez passer un délégué. Contains() ne peut accepter qu'un objet.

30 votes

Contains est également une méthode d'extension contre IEnumerable<T> (bien que certaines collections aient leur propre Contains également la méthode d'instance). Comme vous le dites, Any est plus souple que Contains car vous pouvez lui passer un prédicat personnalisé, mais Contains puede est légèrement plus rapide car elle n'a pas besoin d'effectuer une invocation de délégué pour chaque élément.

2 votes

Fait Tout() effectue l'opération sur tous les objets de la collection ou se termine-t-elle avec la première correspondance ?

2 votes

Au moins selon la source il s'arrête au premier match. All() fonctionne de la même manière.

14voto

tster Points 9948

Cela dépend de la collection. Si vous avez une collection ordonnée, alors Contains pourrait faire une recherche intelligente (binaire, hachage, b-tree, etc.), alors qu'avec `Any() vous êtes essentiellement coincé avec l'énumération jusqu'à ce que vous le trouviez (en supposant LINQ-to-Objects).

Notez également que dans votre exemple, Any() utilise le == qui vérifiera l'égalité référentielle, tandis que l'opérateur Contains utilisera IEquatable<T> ou le Equals() qui peut être remplacée par une autre méthode.

5 votes

Avec .Any, vous pouvez facilement comparer des propriétés. Avec .Contains, vous ne pouvez comparer que des objets et vous avez besoin d'un IEqualityComparer supplémentaire pour comparer des propriétés.

1 votes

@msfanboy : C'est vrai, mais la question portait spécifiquement sur les performances et montrait la comparaison de l'objet entier. Je ne pense donc pas que ce soit pertinent ici.

4voto

Jeff Mercado Points 42075

Je suppose que cela dépendrait du type de myCollection est ce qui dicte comment Contains() est mis en œuvre. Si un arbre binaire trié par exemple, il pourrait chercher plus intelligemment. Il pourrait également prendre en compte le hachage de l'élément. Any() d'autre part, énumère la collection jusqu'à ce que le premier élément qui satisfait à la condition soit trouvé. Il n'y a pas d'optimisations si l'objet avait une méthode de recherche plus intelligente.

0voto

Uwais Points 12

Contains() est également une méthode d'extension qui peut fonctionner rapidement si vous l'utilisez de la bonne manière. Par exemple :

var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();

Cela donnera la requête

SELECT Id FROM Projects INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item

tandis que Any(), d'autre part, itère toujours à travers les O(n).

J'espère que cela va fonctionner....

1 votes

Si vous lisez ceci, vous confondez LINQ et "Linq To SQL". Et là où cette discussion est principalement centrée sur IEnumerable votre réponse est d'environ IQueryable . Je n'ai pas vérifié l'exactitude de ce texte, mais il semble mal placé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X