Étant donné une énorme collection d'objets, y a-t-il une différence de performances entre les éléments suivants?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Étant donné une énorme collection d'objets, y a-t-il une différence de performances entre les éléments suivants?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Réponses:
Contains()
est une méthode d'instance et ses performances dépendent en grande partie de la collection elle-même. Par exemple, Contains()
sur a List
est O (n), tandis que Contains()
sur a HashSet
est O (1).
Any()
est une méthode d'extension, et passera simplement par la collection, en appliquant le délégué sur chaque objet. Il 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.
Contains
est également une méthode d'extension contre IEnumerable<T>
(bien que certaines collections aient également leur propre Contains
méthode d'instance). Comme vous le dites, Any
est plus flexible que Contains
parce que vous pouvez lui transmettre un prédicat personnalisé, mais Contains
peut être légèrement plus rapide car il n'a pas besoin d'effectuer un appel de délégué pour chaque élément.
All()
fonctionne de manière similaire.
Cela dépend de la collection. Si vous avez une collection ordonnée, vous Contains
pouvez faire une recherche intelligente (binaire, hachage, b-tree, etc.), tandis qu'avec `Any () vous êtes fondamentalement coincé avec l'énumération jusqu'à ce que vous la trouviez (en supposant LINQ-to-Objects) .
Notez également que dans votre exemple, Any()
utilise l' ==
opérateur qui vérifiera l'égalité référentielle, tandis que Contains
utilisera IEquatable<T>
ou la Equals()
méthode, qui pourrait être remplacée.
Je suppose que cela dépendrait du type de système myCollection
qui dicte la manière dont il Contains()
est mis en œuvre. Si un arbre binaire trié par exemple, il pourrait rechercher plus intelligemment. Il peut également prendre en compte le hachage de l'élément. Any()
d'autre part, l'énumérera à travers la collection jusqu'à ce que le premier élément qui satisfait la condition soit trouvé. Il n'y a pas d'optimisation pour savoir si l'objet avait une méthode de recherche plus intelligente.
Contains () est également une méthode d'extension qui peut fonctionner rapidement si vous l'utilisez correctement. 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'un autre côté itère toujours à travers le O (n).
J'espère que cela fonctionnera ....