É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 Listest O (n), tandis que Contains()sur a HashSetest 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.
Containsest également une méthode d'extension contre IEnumerable<T>(bien que certaines collections aient également leur propre Containsméthode d'instance). Comme vous le dites, Anyest plus flexible que Containsparce 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 Containspouvez 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 Containsutilisera IEquatable<T>ou la Equals()méthode, qui pourrait être remplacée.
Je suppose que cela dépendrait du type de système myCollectionqui 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 ....