2010-05-21 21 views
6

es la siguiente:¿Es Linq más rápido, más lento o lo mismo?

Box boxToFind = AllBoxes.FirstOrDefault(box => box.BoxNumber == boxToMatchTo.BagNumber); 

más rápido o más lento que esto:

Box boxToFind ; 
foreach (Box box in AllBoxes) 
{ 
    if (box.BoxNumber == boxToMatchTo.BoxNumber) 
    { 
     boxToFind = box; 
    } 
} 

Ambos me dan el resultado Busco (boxToFind). Esto se ejecutará en un dispositivo móvil que necesito ser consciente del rendimiento.

+2

Su primer método no se compilará. Donde devuelve un IEnumerable. Para ser equivalente al último, tendrías que hacer AllBoxes.Last (box => ...) –

+0

Buen punto. Cambié mi primer método. (Aunque no utilicé el último, porque "debería" tener solo valores únicos) – Vaccano

+0

Se compilará el segundo método, pero le dará el último cuadro que coincida. Pon un descanso; cuando salgas del if. – Rubys

Respuesta

8

Debe ser casi lo mismo, excepto que debe llamar al First (o, para que coincida con su código, Last), no a Where.
Llamar a Where le dará un conjunto de elementos coincidentes (un IEnumerable<Box>); solo quieres un objeto que coincida.

En general, al utilizar LINQ, debe tener en cuenta la ejecución diferida. En su caso particular, es irrelevante, ya que obtiene un solo artículo.

+1

FirstOrDefault para evitar excepciones – hunter

+11

@hunter: A menos que quiera una excepción. – SLaks

+0

@SLaks O sabe que siempre existe un elemento adecuado. – Thomas

2

Si lo tuyo es la micro-optimización, LINQ funciona peor, this is just one article, hay muchas otras publicaciones que puedes encontrar.

+8

** La optimización pre-madura es la raíz de todo mal. ** Esto es altamente improbable que sea relevante para él. – SLaks

+0

No sé si leíste los comentarios para ese artículo, pero la mayor parte del problema no fue la iteración, sino el modelo implícito en su código original. Anders Hejlsberg señaló que una consulta que no involucraba operaciones de conversión por iteración estaba razonablemente cerca del bucle for. –

0

Lo más rápido es cuando está utilizando for loop. Pero la diferencia es tan pequeña que la ignoras. Solo importará si está construyendo una aplicación en tiempo real, pero entonces para esas aplicaciones ¡quizás C# no sea la mejor opción!

8

La diferencia no es importante a menos que haya identificado este ciclo en particular como un cuello de botella de rendimiento a través del perfilado.

Si el perfilado encuentra un problema, entonces querrá buscar otro almacenamiento. Almacene los datos en un diccionario que proporciona una búsqueda más rápida que el bucle a través de una matriz.

+0

¿Un diccionario proporciona una búsqueda más rápida que una matriz? Seguro como el infierno no lo hace. Los diccionarios están respaldados por matrices, con cálculos adicionales cada vez que accede a un elemento. Por lo tanto, es imposible que un diccionario sea más rápido que una matriz en una iteración. – Rubys

+5

@Rubys: las búsquedas del diccionario son O (1), iterar a través de una matriz es O (n), por lo que las búsquedas del diccionario son más rápidas para una colección lo suficientemente grande (suponiendo una función hash sensible). – Lee

+0

@Rubys, Dictionary está respaldado por una matriz de matrices. Un hashcode se usa para identificar exactamente qué elemento en la primera matriz recuperar. No hay bucle, solo un cálculo matemático simple. Eso te da el segundo conjunto, a menudo denominado cubo. Luego, el código recorre el cubo para encontrar el artículo exacto.Un buen tamaño de recopilación y un código hash darán lugar a cubos que tienen solo unos pocos elementos. El resultado final es que el diccionario es significativamente más rápido que un bucle de matriz. –

1

La optimización de micro te matará.
Primero, termine toda la clase, luego, si tiene problemas de rendimiento, ejecute un generador de perfiles y verifique las zonas activas de la aplicación.
Asegúrate de estar usando los mejores algoritmos que puedas, y luego. Utiliza micro optimizaciones como esta.

En caso de que ya lo hicieron:
lenta -> Fast
LINQ < foreach < para < inseguro para (La última opción no es recomendable).
Las abstracciones harán que su código sea más lento, el 95% del tiempo.

0

Si AllBoxes es un IQueryable, puede ser más rápido que el bucle, porque el consultable podría tener una implementación optimizada de Where-operation (por ejemplo, un acceso indexado).

+0

@Sam: IQueryable hereda IEnumerable, por lo que un bucle foreach funciona – Rauhotz

0

LINQ es absolutamente 100% más lento

Depende de lo que está tratando de lograr en su programa, pero en su mayor parte esto es lo que yo llamaría CÓDIGO DEL PROGRAMADOR LAZY ...

Va a esencialmente "quedarse afuera" si está trabajando cualquier consulta compleja, combinaciones, etc. pos total para esos tipos de funciones/métodos, simplemente no lo use. Si haces esto de la manera difícil/larga, serás mucho más feliz a largo plazo ... y el rendimiento será un mundo aparte.

NOTA:

Definitivamente no recomendaría LINQ para cualquier programa construido para tareas de velocidad/sincronización/cómputo (es decir, el comercio HFT &/o en las operaciones de I-0-i para empezar).

PROBADO:

Se tomó casi 10 segundos para completar una combinación en "LINQ" vs. < 1 milisegundo.

Cuestiones relacionadas