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 aListes O (n), mientras queContains()en aHashSetes 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
Containstambién es un método de extensión contraIEnumerable<T>(aunque algunas colecciones también tienen su propioContainsmétodo de instancia). Como dice,Anyes más flexible queContainsporque puede pasarle un predicado personalizado, peroContainspodrí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
Containspodrí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, mientrasContainsque usaráIEquatable<T>o elEquals()método, que podría ser anulado.fuente
Supongo que dependerá del tipo de
myCollectiones 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.Itemmientras que Any () por otro lado siempre itera a través de O (n).
Espero que esto funcione ...
fuente