Dada una gran colección de objetos, ¿hay alguna diferencia de rendimiento entre los siguientes?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
c#
linq
performance
benchmarking
SDReyes
fuente
fuente
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 aList
es O (n), mientras queContains()
en aHashSet
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.fuente
Contains
también es un método de extensión contraIEnumerable<T>
(aunque algunas colecciones también tienen su propioContains
método de instancia). Como dice,Any
es más flexible queContains
porque puede pasarle un predicado personalizado, peroContains
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, mientrasContains
que usaráIEquatable<T>
o elEquals()
método, que podría ser anulado.fuente
Supongo que dependerá del tipo de
myCollection
es el que dicta cómoContains()
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.fuente
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 ...
fuente