En el punto de vista del rendimiento, ¿qué debería usar "Anidado foreach" o "lambda/linq consultas"?"Nested foreach" vs "lambda/linq query" performance (LINQ-to-Objects)
Respuesta
Escriba el código más claro que pueda, y luego haga una evaluación comparativa y perfil para descubrir cualquier problema de rendimiento. Si tiene tiene problemas de rendimiento, puede experimentar con códigos diferentes para determinar si es más rápido o no (midiendo todo el tiempo con datos tan realistas como sea posible) y luego juzgar si la mejora en el rendimiento vale la pena la legibilidad golpeó.
Un enfoque foreach
directo será más rápido que LINQ en muchos casos. Por ejemplo, considere:
var query = from element in list
where element.X > 2
where element.Y < 2
select element.X + element.Y;
foreach (var value in query)
{
Console.WriteLine(value);
}
Ahora bien, hay dos cláusulas where
y una cláusula de select
, por lo que cada elemento eventual tiene que pasar a través de tres iteradores. (. Es evidente que los dos cláusulas donde se podrían combinar en este caso, pero estoy haciendo un punto general)
Ahora compararlo con el código directa:
foreach (var element in list)
{
if (element.X > 2 && element.Y < 2)
{
Console.WriteLine(element.X + element.Y);
}
}
Eso hará correr más rápido, ya que tiene menos aros para atravesar. Lo más probable es que la salida de la consola empequeñezca el costo del iterador, y ciertamente preferiría la consulta LINQ.
EDIT: Para responder sobre "foreach anidados" bucles ... normalmente están representados aquellos con SelectMany
o una segunda cláusula from
:
var query = from item in firstSequence
from nestedItem in item.NestedItems
select item.BaseCount + nestedItem.NestedCount;
Aquí sólo estamos agregando un único repetidor adicional, porque somos d ya utilizar un iterador adicional por artículo en la primera secuencia debido al ciclo anidado foreach
. Todavía hay un poco de sobrecarga, incluida la sobrecarga de hacer la proyección en un delegado en lugar de "en línea" (algo que no mencioné antes), pero aún así no será muy diferente al rendimiento anidado-foreach.
Esto no quiere decir que no puedas disparar en el pie con LINQ, por supuesto. Puede escribir preguntas estupendamente ineficientes si no involucra su cerebro primero, pero eso no es exclusivo de LINQ ...
Es más complejo en eso. En definitiva, gran parte de LINQ-to-Objects es (detrás de escena) un bucle foreach
, pero con la sobrecarga adicional de un poco de bloques de abstracción/iterador/etc. Sin embargo, a menos que haga cosas muy diferentes en sus dos versiones (foreach vs. LINQ), ambos deberían ser O (N).
La verdadera pregunta es: ¿hay una mejor manera de escribir su algoritmo específico que significa que foreach
sería ineficaz? ¿Y puede LINQ hacerlo por ti?
Por ejemplo, LINQ facilita los datos de hash/grupo/clasificación.
Si lo hace
foreach(Customer c in Customer)
{
foreach(Order o in Orders)
{
//do something with c and o
}
}
que llevará a cabo Customer.Count * Orden.Contar iteraciones
si lo hace
var query =
from c in Customer
join o in Orders on c.CustomerID equals o.CustomerID
select new {c, o}
foreach(var x in query)
{
//do something with x.c and x.o
}
que llevará a cabo iteraciones Customer.Count + Order.Count, porque Enumerable.Join se implementa como un HashJoin.
excelente respuesta con una buena explicación –
Eso es porque está ejecutando dos algoritmos diferentes; estás comparando manzanas con naranjas. No veo cómo esto es relevante para la pregunta planteada. – mquander
Su foreach anidados es en realidad equivalente a SelectMany, no unirse a - es decir, desde C en cliente o en las órdenes ... (sin unión) –
Se ha dicho antes, pero que merece la repetición.
Desarrolladores nunca se sabe dónde está el cuello de botella es hasta que se agoten las pruebas de rendimiento.
Lo mismo es cierto para comparar la técnica de la A a la técnica de B. A menos que haya una gran diferencia a continuación sólo hay que probarlo. Puede ser obvio si tienes un escenario O (n) vs O (n^x), pero dado que el material LINQ es principalmente compilación de brujería, merece un perfil.
Además, a menos que su proyecto esté en producción y haya perfilado el código y encontrado que ese bucle está ralentizando su ejecución, déjelo como lo prefiera para la legibilidad y el mantenimiento. La optimización prematura es el diablo.
Si bien es cierto que no puede anticipar realmente los cuellos de botella de rendimiento, también es cierto que la mayoría de los problemas de rendimiento están diseñados, se encuentran muy tarde en el ciclo de vida de desarrollo y, por lo tanto, son difíciles de descifrar. Hay mucho para decir para siempre tener un ojo abierto a las implicaciones de rendimiento de las decisiones de diseño e implementación que está haciendo, en lugar de codificar alegremente esperando que todo esté bien. – Mike
Una gran ventaja es que el uso de consultas de Linq-To-Objects le da la capacidad de pasar fácilmente la consulta a PLinq y hacer que el sistema realice automáticamente la operación en la cantidad correcta de hilos para el sistema actual.
Si está utilizando esta técnica en grandes conjuntos de datos, que es una muy susceptibles a una gran victoria para muy pocos problemas.
Es cierto, pero también hay equivalentes paralelos propuestos para foreach también. http://www.danielmoth.com/Blog/2009/01/parallelising-loops-in-net-4.html – jpierson
- 1. Hibernate Query vs Criteria Performance
- 2. Nested Query o Joins
- 3. PHP foreach con Nested Array?
- 4. CALayer performance vs. UIImageView performance
- 5. Xcode Workspace vs Nested Projects
- 6. System.Reflection vs Generics - performance
- 7. strftime performance vs. snprintf
- 8. performance stringbuf vs cadena
- 9. VS 2010 Performance Explorer
- 10. UPDATE vs INSERT performance
- 11. LINQ + Foreach vs Foreach + Si
- 12. Javascript - Argumentos Vs Funciones anidadas Vs Performance
- 13. array_walk vs array_map vs foreach
- 14. ?: Operador vs. Si Statement Performance
- 15. SQL JOIN vs IN performance?
- 16. Boost.Variant Vs Virtual Interface Performance
- 17. HTTPListener vs Native HTTP performance
- 18. prepare() vs query() mysqli
- 19. foreach vs someList.ForEach() {}
- 20. Nested Parallel.ForEach Loops
- 21. Mysql VIEWS vs. PHP query
- 22. consultas MySQL vs php foreach múltiple bucles
- 23. Mysql middle int vs. int performance
- 24. Scala: Mutable vs. Inmutable Object Performance - OutOfMemoryError
- 25. Static Vs Instance Method Performance C#
- 26. Abysmal OpenCL ImageSampling performance vs OpenGL TextureSampling
- 27. AJAX Polling vs. WebSockets Mobile Performance
- 28. C# performance question: typeof (MyClass) vs. this.GetType()
- 29. Linq to Sql vs Entity Framework Performance
- 30. DataTrigger vs databinding with converter performance wise
La primera frase debe ser impreso como una bandera y colgado en cada departamento de programación. –
Jon ... Eres increíble ... ¡Gracias de corazón! –