Dada una gran colección de objetos, ¿hay alguna diferencia de rendimiento entre los siguientes?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Dada una gran colección de objetos, ¿hay alguna diferencia de rendimiento entre los siguientes?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Respuestas:
Contains()
es un método de instancia y su rendimiento depende en gran medida de la colección en sí. Por ejemplo, Contains()
en a List
es O (n), mientras que Contains()
en a HashSet
es O (1).
Any()
es un método de extensión, y simplemente recorrerá la colección, aplicando el delegado en cada objeto. Por tanto, tiene una complejidad de O (n).
Any()
sin embargo, es más flexible ya que puede pasar un delegado. Contains()
solo puede aceptar un objeto.
Contains
también es un método de extensión contra IEnumerable<T>
(aunque algunas colecciones también tienen su propio Contains
método de instancia). Como dice, Any
es más flexible que Contains
porque puede pasarle un predicado personalizado, pero Contains
podría ser un poco más rápido porque no necesita realizar una invocación delegada para cada elemento.
All()
opera de manera similar.
Depende de la colección. Si tiene una colección ordenada, entonces Contains
podría hacer una búsqueda inteligente (binaria, hash, árbol b, etc.), mientras que con `Any () básicamente está atascado con la enumeración hasta que la encuentre (asumiendo LINQ-to-Objects) .
También tenga en cuenta que en su ejemplo, Any()
está usando el ==
operador que verificará la igualdad de referencia, mientras Contains
que usará IEquatable<T>
o el Equals()
método, que podría ser anulado.
Supongo que dependerá del tipo de myCollection
es el que dicta cómo Contains()
se implementa. Si, por ejemplo, un árbol binario ordenado, podría buscar de forma más inteligente. También puede tener en cuenta el hash del elemento. Any()
por otro lado se enumerará a través de la colección hasta que se encuentre el primer elemento que satisfaga la condición. No hay optimizaciones para si el objeto tenía un método de búsqueda más inteligente.
Contains () también es un método de extensión que puede funcionar rápidamente si lo usa de la manera correcta. Por ejemplo:
var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();
Esto le dará a la consulta
SELECT Id
FROM Projects
INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item
mientras que Any () por otro lado siempre itera a través de O (n).
Espero que esto funcione ...