2010-07-01 24 views
81

Escribo un administrador de Mesh Rendering y pensé que sería una buena idea agrupar todas las mallas que usan el mismo sombreador y luego renderizarlas mientras estoy en ese paso de sombreado.¿Es una instrucción LINQ más rápida que un bucle 'foreach'?

Actualmente estoy usando un ciclo foreach, pero me preguntaba si la utilización de LINQ podría darme un aumento en el rendimiento.

+1

posible duplicado de [ "foreach anidados" vs rendimiento "lambda/LINQ consulta" (LINQ a Objetos)] (http://stackoverflow.com/questions/1044236/nested-foreach- vs-lambda-linq-query-performancelinq-to-objects) –

+1

Considere configurar @ la respuesta de MarcGravell a la aceptada, existen situaciones, por ejemplo, linq a sql, donde linq es más rápido que for/foreach. – paqogomez

Respuesta

144

¿Por qué LINQ debe ser más rápido? También usa bucles internamente.

La mayoría de las veces, LINQ será un poco más lento porque introduce una sobrecarga. No use LINQ si le importa mucho el rendimiento. Use LINQ porque quiere un código más corto, legible y fácil de mantener.

+6

Entonces, ¿su experiencia es que LINQ es más rápido y hace que el código sea más difícil de leer y de mantener? Por favor explique. – codymanix

+56

Creo que lo tenías al revés. Él está diciendo que LINQ es más LENTO. Esto se debe a un exceso de cabeza. También dice que LINQ es más fácil de leer y mantener. –

+1

Lo siento. Mientras tanto, teníamos muchas cosas en las que comparamos linq y for o foreach performance, y la mayoría de las veces linq era más rápido. – Offler

14

Creo que es mejor utilizar LINQ en un circuito foreach, porque le da un código mucho más limpio y fácil de entender. Pero LINQ es más lento que foreach. Para obtener más, consulte el artículo LINQ vs FOREACH vs FOR Loop Performance.

48

LINQ-to-Objects generalmente va a agregar algunos gastos indirectos marginales (iteradores múltiples, etc.). Todavía tiene que hacer los bucles, y tiene delegar invoca, y generalmente tendrá que hacer un poco de desreferencia extra para llegar a las variables capturadas etc. En la mayoría de código esto será prácticamente indetectable, y más de que ofrece el más simple de entender el código.

con otros proveedores LINQ como LINQ a SQL, ya que la consulta se puede filtrar en el servidor debería ser mucho mejor de un piso foreach, pero lo más probable es que no hubiera hecho una manta "select * from foo"todos modos, por lo que no es necesariamente una comparación justa.

Re PLINQ; el paralelismo puede reducir el tiempo transcurrido, pero el tiempo total de CPU generalmente aumentará un poco debido a los gastos generales de gestión de subprocesos, etc.

+0

En otra respuesta, aludió * no * con LINQ en colecciones en memoria, p. Ej. 'List '; en su lugar, debería usar un bloque 'foreach' en estas colecciones. La recomendación de usar 'foreach' en estos contextos tiene sentido. Mi preocupación: ¿debería reemplazar solo consultas LINQ con 'foreach' * si * detecto un problema de rendimiento? En adelante, consideraré el 'foreach' primero. – IAbstract

13

LINQ ahora es más lento, pero puede ser más rápido en algún momento. Lo bueno de LINQ es que no tiene que preocuparse por cómo funciona. Si se piensa en un nuevo método que es increíblemente rápido, la gente de Microsoft puede implementarlo sin siquiera decírselo y su código sería mucho más rápido.

Más importante aún, LINQ es mucho más fácil de leer. Esa debería ser suficiente razón.

+3

Me gusta la línea "Microsoft puede implementarlo" ¿es posible, quiero decir que es posible sin actualizar el marco? – Shrivallabh

+0

LINQ nunca será más rápido que la implementación nativa, ya que al final del día, se traduce a la implementación nativa. No hay instrucciones especiales de CPU LINQ y registros LINQ que se puedan usar para traducir códigos de máquina LINQ más rápidos, y si los hubiera, también serían utilizados por códigos que no sean LINQ. – mg30rg

7

Probablemente debería tenerse en cuenta que el ciclo for es más rápido que el foreach. Por lo tanto, para la publicación original, si le preocupa el rendimiento en un componente crítico como un procesador, use un bucle for.

Referencia: In .NET, which loop runs faster, 'for' or 'foreach'?

2

Yo estaba interesado en esta cuestión, por lo que hizo una prueba en este momento. Usando .NET Framework 4.5.2 en una CPU Intel (R) Core (TM) i3-2328M @ 2.20 GHz, 2200 Mhz, 2 Core (s) con 8 GB de ram corriendo Microsoft Windows 7 Ultimate.

Parece que LINQ podría ser más rápido que para cada ciclo. Éstos son los resultados que obtuve:

Exists=True 
Time=174 
Exists=True 
Time=149 

sería interesante si algunos de ustedes podrían copiar & pega este código en una aplicación de consola y prueba también. Antes de probar con un objeto (Empleado), probé la misma prueba con números enteros. LINQ fue más rápido allí también.

public class Program 
{ 

    public class Employee 
    { 
     public int id; 
     public string name; 
     public string lastname; 
     public DateTime dateOfBirth; 

     public Employee(int id,string name,string lastname,DateTime dateOfBirth) 
     { 
      this.id = id; 
      this.name = name; 
      this.lastname = lastname; 
      this.dateOfBirth = dateOfBirth; 

     } 

    } 

    public static void Main() 
    { 

     StartObjTest(); 
    } 

    #region object test 

    public static void StartObjTest() 
    { 
     List<Employee> items = new List<Employee>(); 

     for (int i = 0; i < 10000000; i++) 
     { 
      items.Add(new Employee(i,"name" + i,"lastname" + i,DateTime.Today)); 
     } 

     Test3(items, items.Count-100); 
     Test4(items, items.Count - 100); 

     Console.Read(); 
    } 


    public static void Test3(List<Employee> items, int idToCheck) 
    { 

     Stopwatch s = new Stopwatch(); 
     s.Start(); 

     bool exists = false; 
     foreach (var item in items) 
     { 
      if (item.id == idToCheck) 
      { 
       exists = true; 
       break; 
      } 
     } 

     Console.WriteLine("Exists=" + exists); 
     Console.WriteLine("Time=" + s.ElapsedMilliseconds); 

    } 

    public static void Test4(List<Employee> items, int idToCheck) 
    { 

     Stopwatch s = new Stopwatch(); 
     s.Start(); 

     bool exists = items.Exists(e => e.id == idToCheck); 

     Console.WriteLine("Exists=" + exists); 
     Console.WriteLine("Time=" + s.ElapsedMilliseconds); 

    } 

    #endregion 


    #region int test 
    public static void StartIntTest() 
    { 
     List<int> items = new List<int>(); 

     for (int i = 0; i < 10000000; i++) 
     { 
      items.Add(i); 
     } 

     Test1(items, -100); 
     Test2(items, -100); 

     Console.Read(); 
    } 

    public static void Test1(List<int> items,int itemToCheck) 
    { 

     Stopwatch s = new Stopwatch(); 
     s.Start(); 

     bool exists = false; 
     foreach (var item in items) 
     { 
      if (item == itemToCheck) 
      { 
       exists = true; 
       break; 
      } 
     } 

     Console.WriteLine("Exists=" + exists); 
     Console.WriteLine("Time=" + s.ElapsedMilliseconds); 

    } 

    public static void Test2(List<int> items, int itemToCheck) 
    { 

     Stopwatch s = new Stopwatch(); 
     s.Start(); 

     bool exists = items.Contains(itemToCheck); 

     Console.WriteLine("Exists=" + exists); 
     Console.WriteLine("Time=" + s.ElapsedMilliseconds); 

    } 

    #endregion 

} 
0

Esto es realmente una pregunta bastante compleja. Linq hace que ciertas cosas sean muy fáciles de hacer, que si las implementa usted mismo, puede tropezar con (por ejemplo, linq. Except()). Esto se aplica particularmente a PLinq, y especialmente a la agregación paralela según lo implementado por PLinq.

En general, para código idéntico, linq será más lento, debido a la sobrecarga de la invocación de delegado.

Sin embargo, si se va a procesar una gran variedad de datos, y la aplicación de cálculos relativamente simples a los elementos, obtendrá un enorme aumento del rendimiento si:

  1. Se utiliza una matriz para almacenar los datos.
  2. Utiliza un bucle for para acceder a cada elemento (a diferencia de foreach o linq).

    • Nota: Cuando se comparta, todos deben recordar que si usa la misma matriz/lista para dos pruebas consecutivas, la memoria caché de la CPU hará que la segunda sea más rápida. *
Cuestiones relacionadas