¿Es el método Linq Count(
) más rápido o más lento que List<>.Count
o Array.Length
?¿El conteo de Linq() es más rápido o más lento que List.Count o Array.Length?
Respuesta
En general Más lento. El recuento de LINQ en general es una operación O(N)
, mientras que List.Count
y Array.Length
tienen la garantía de ser O(1)
.
Sin embargo, en algunos casos LINQ será el caso especial del parámetro IEnumerable<T>
mediante conversión a ciertos tipos de interfaz como IList<T>
o ICollection<T>
. A continuación, utilizará ese método Count para realizar una operación real Count()
. Por lo tanto, volverá a bajar al O(1)
. Pero aún pagas la sobrecarga menor del reparto y la llamada a la interfaz.
@Marc, agregué ese cavaet. – JaredPar
No estoy seguro, pero creo que si List.Count() se ejecuta en un IQueryable ejecutará el comando select count (*) sql. pero si se ejecuta List.Count enumerará a través de todos los elementos y luego devolverá el conteo. Si este último, List.Count() sería más rápido la mayor parte del tiempo. – Jose
@Jared, la respuesta de Marcs es más precisa, la comprobación solo se realiza para ICollection
Creo que si llama a Linq.Count() en una ICollection o IList (como una lista de arreglos o una lista), simplemente devolverá el valor de la propiedad Count. Por lo tanto, el rendimiento será aproximadamente el mismo en las colecciones simples.
ArrayList no es IEnumerable
El método Enumerable.Count()
comprueba ICollection<T>
, usando .Count
- por lo que en el caso de matrices y listas, no es mucho más ineficiente (solo un nivel extra de indirección).
En realidad con las matrices se obtienen 2 capas de direccionamiento indirecto, ver mi respuesta: p –
Yo diría que depende de la lista. Si es un IQueryable que es una tabla en un db en algún lugar, entonces Count() será mucho más rápido porque no tiene que cargar todos los objetos. Pero si la lista está en memoria, supongo que la propiedad Count sería más rápida si no es igual.
Marc tiene la respuesta correcta, pero el diablo está en los detalles.
En mi máquina:
- Para las matrices .length es aproximadamente 100 veces más rápido que .Count()
- para las listas .Count es aproximadamente 10 veces más rápido que .Count() - Nota: lo haría esperar un rendimiento similar de todas las colecciones que implementan
IList<T>
matrices comienzan más lento desde .length implica únicamente una sola operación, .Count en arrays consiste en una capa de direccionamiento indirecto. Entonces, .Count en matrices comienza 10 veces más lento (en mi máquina), lo que podría ser una de esas razones por las que la interfaz se implementa explícitamente. Imagine si tuviera un objeto con dos propiedades públicas, .Count y .Length. Ambos hacen exactamente lo mismo pero .Count es 10 veces más lento.
Por supuesto, esto no hace mucha diferencia, ya que tendría que estar contando sus matrices y listas millones de veces por segundo para sentir un golpe de rendimiento.
Código:
static void TimeAction(string description, int times, Action func) {
var watch = new Stopwatch();
watch.Start();
for (int i = 0; i < times; i++) {
func();
}
watch.Stop();
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}
static void Main(string[] args) {
var array = Enumerable.Range(0, 10000000).ToArray();
var list = Enumerable.Range(0, 10000000).ToArray().ToList();
// jit
TimeAction("Ignore and jit", 1 ,() =>
{
var junk = array.Length;
var junk2 = list.Count;
array.Count();
list.Count();
});
TimeAction("Array Length", 1000000,() => {
var tmp1 = array.Length;
});
TimeAction("Array Count()", 1000000,() =>
{
var tmp2 = array.Count();
});
TimeAction("Array Length through cast", 1000000,() =>
{
var tmp3 = (array as ICollection<int>).Count;
});
TimeAction("List Count", 1000000,() =>
{
var tmp1 = list.Count;
});
TimeAction("List Count()", 1000000,() =>
{
var tmp2 = list.Count();
});
Console.ReadKey();
}
Resultados:
Array Length Time Elapsed 3 ms Array Count() Time Elapsed 264 ms Array Length through cast Time Elapsed 16 ms List Count Time Elapsed 3 ms List Count() Time Elapsed 18 ms
Afortunadamente 'collection.Count/Length' es más legible que' collection.Count() '. Casos raros donde el código más bonito es más eficiente: P – nawfal
Solo FYI, veo una pequeña diferencia entre '(array como ICollection
algo de información adicional - LINQ contar - la diferencia entre usar y no puede ser enorme - y esto no tiene que ser más ' grandes colecciones tampoco. Tengo una colección formada por linq para objetos con aproximadamente 6500 elementos (grande ... pero no enorme de ninguna manera). Count() en mi caso toma varios segundos. Convirtiendo en una lista (o matriz, qué), el conteo es virtualmente inmediato. Tener esto en cuenta en un bucle interno significa que el impacto podría ser enorme. Count enumera todo.Una matriz y una lista son "autoconscientes" de sus longitudes y no es necesario enumerarlas. Cualquier declaración de depuración (log4net por ejemplo) que haga referencia a este conteo() también ralentizará considerablemente todo. Hágase un favor y si necesita referenciar esto a menudo, guarde el tamaño de conteo y solo llámelo una vez en una colección LINQ a menos que lo convierta en una lista y luego pueda hacer referencia sin un golpe de rendimiento.
Aquí hay una prueba rápida de lo que estaba hablando anteriormente. Nótese que cada vez que llamamos a Count() nuestro tamaño de colección cambia ... por lo tanto, la evaluación ocurre, que es más que una operación de 'recuento' esperada. Algo a tener en cuenta:)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinqTest
{
class TestClass
{
public TestClass()
{
CreateDate = DateTime.Now;
}
public DateTime CreateDate;
}
class Program
{
static void Main(string[] args)
{
//Populate the test class
List list = new List(1000);
for (int i=0; i<1000; i++)
{
System.Threading.Thread.Sleep(20);
list.Add(new TestClass());
if(i%100==0)
{
Console.WriteLine(i.ToString() + " items added");
}
}
//now query for items
var newList = list.Where(o=> o.CreateDate.AddSeconds(5)> DateTime.Now);
while (newList.Count() > 0)
{
//Note - are actual count keeps decreasing.. showing our 'execute' is running every time we call count.
Console.WriteLine(newList.Count());
System.Threading.Thread.Sleep(500);
}
}
}
}
list.Where devuelve un IEnumerable por lo que no obtienes accesos directos con Count() ... si lo materializaste verías muy bien perf (por ejemplo: 'list.Where (o => o.CreateDate.AddSeconds (5)> DateTime .Now) .ToList() ') –
- 1. ¿Es Linq más rápido, más lento o lo mismo?
- 2. Es costoso hacer array.length o list.count en un bucle
- 3. que es más rápido? Declaración o PreparedStatement
- 4. que es más rápido, equalsIgnoreCase o compareToIgnoreCase
- 5. ¿doble o flotante, que es más rápido?
- 6. ¿Es O (log n) siempre más rápido que O (n)
- 7. servidor SQL 'en' o 'o' - que es más rápido
- 8. cuando es Java más rápido que C++ (o cuando JIT es más rápido que precompilado)?
- 9. Más rápido que os.walk o glob?
- 10. Es LINQ generalmente más lento que una instrucción SQL igual
- 11. ¿Quién es más rápido: PEG o GLR?
- 12. ¿Qué es más rápido, XPath o Regexp?
- 13. escribe o imprime, ¿qué es más rápido?
- 14. ¿qué es más rápido: recrear o borrar()?
- 15. ¿Qué es más rápido: JDBC o JNDI?
- 16. ¿Qué es más rápido EN O?
- 17. ¿Qué es más rápido? Comparación o asignación?
- 18. ¿Qué es más rápido: Union o Concat?
- 19. ¿Qué es más rápido, INSTR o LIKE?
- 20. ¿Cuál es más rápido COALESCE O ISNULL?
- 21. ¿Es + = más rápido que - =?
- 22. numpy.max o max? ¿Cuál es más rápido?
- 23. Double.TryParse o Convert.ToDouble - ¿Qué es más rápido y más seguro?
- 24. Izquierda JOIN más rápido o Inner Join más rápido?
- 25. Que es más rápido, 'find -exec' o 'find | xargs -0 '?
- 26. En javascript, ¿acceder a 'window.Math' es más lento o más rápido que acceder al objeto 'Math' sin la 'ventana'?
- 27. En MySQL, ¿es más rápido eliminar e insertar o es más rápido actualizar las filas existentes?
- 28. ¿Qué es más rápido? Struct array o DataTable
- 29. ¿Es más lento que elsif?
- 30. ¿Cuál es el protocolo más rápido, ssh o git?
La manera más fácil de saber es probarlo. Envuelva ambos en llamadas a los métodos apropiados en Cronómetro, hágalo algunos millones de veces, y lo sabrá. –
Probablemente no valga la pena que no haya una diferencia notable en la velocidad, a menos que hablemos de colecciones seriamente grandes. Simplemente use cualquiera que sea más fácil de leer/mantener. – Hardwareguy