É uma instrução LINQ mais rápida que um loop ‘foreach’?

Estou escrevendo um gerenciador de renderização de malha e pensei que seria uma boa idéia agrupar todas as malhas que usam o mesmo sombreador e renderizá-las enquanto eu estiver nesse shader pass.

No momento, estou usando um loop foreach , mas imagino se a utilização do LINQ pode me dar um aumento de desempenho?

Por que LINQ deveria ser mais rápido? Ele também usa loops internamente.

Na maioria das vezes, o LINQ será um pouco mais lento porque introduz a sobrecarga. Não use LINQ se você se importa muito com o desempenho. Use o LINQ porque você quer um código menor, mais legível e de fácil manutenção.

LINQ-to-Objects geralmente vai adicionar algumas sobrecargas marginais (múltiplos iteradores, etc). Ele ainda tem que fazer os loops, e tem delegado chama, e geralmente terá que fazer alguma desreferenciação extra para obter variables ​​capturadas, etc. Na maioria dos códigos isso será virtualmente indetectável, e mais do que o permitido pelo mais simples de entender o código.

Com outros provedores LINQ, como o LINQ to SQL, então, como a consulta pode filtrar no servidor, ela deve ser muito melhor do que um flat, mas provavelmente você não teria feito um cobertor "select * from foo" , então isso não é necessariamente uma comparação justa.

Re PLINQ; o paralelismo pode reduzir o tempo decorrido , mas o tempo total da CPU normalmente aumentará um pouco devido às despesas gerais do gerenciamento de threads, etc.

Eu acho que o LINQ é melhor usar um loop foreach , porque ele fornece um código muito mais limpo e fácil de entender. Mas o LINQ é mais lento que o foreach . Para obter mais, leia o artigo LINQ vs FOREACH vs FOR Loop Performance .

O LINQ é mais lento agora, mas pode ficar mais rápido em algum momento. A coisa boa sobre o LINQ é que você não precisa se preocupar sobre como ele funciona. Se um novo método for pensado de forma incrivelmente rápida, as pessoas da Microsoft podem implementá-lo sem nem mesmo dizer a você e seu código seria muito mais rápido.

Mais importante ainda, o LINQ é muito mais fácil de ler. Isso deveria ser razão suficiente.

Você pode obter um aumento de desempenho se usar o LINQ paralelo para vários núcleos. Veja Parallel LINQ (PLINQ) (MSDN).

Deve ser notado que o loop for é mais rápido que o foreach . Portanto, para o post original, se você estiver preocupado com o desempenho em um componente crítico, como um renderizador, use um loop for .

Referência: No .NET, qual loop é executado mais rapidamente, ‘for’ ou ‘foreach’?

Eu estava interessado nessa questão, então fiz um teste agora. Usando o .NET Framework 4.5.2 em uma CPU i3-2328M Intel (R) Core (TM) a 2.20GHz, 2200 Mhz, 2 Núcleo (s) com 8GB de RAM executando o Microsoft Windows 7 Ultimate.

Parece que o LINQ pode ser mais rápido do que para cada loop. Aqui estão os resultados que recebi:

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

Seria interessante se alguns de vocês pudessem copiar e colar esse código em um aplicativo de console e testar também. Antes de testar com um object (Employee) eu tentei o mesmo teste com inteiros. LINQ foi mais rápido lá também.

 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 items = new List(); 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 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 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 items = new List(); for (int i = 0; i < 10000000; i++) { items.Add(i); } Test1(items, -100); Test2(items, -100); Console.Read(); } public static void Test1(List 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 items, int itemToCheck) { Stopwatch s = new Stopwatch(); s.Start(); bool exists = items.Contains(itemToCheck); Console.WriteLine("Exists=" + exists); Console.WriteLine("Time=" + s.ElapsedMilliseconds); } #endregion } 

Esta é realmente uma questão bastante complexa. Linq faz certas coisas muito fáceis de fazer, que se você as implementar você mesmo, você pode tropeçar (por exemplo, linq .Except ()). Isso se aplica particularmente ao PLinq e, especialmente, à agregação paralela implementada pelo PLinq.

Em geral, para código idêntico, o linq será mais lento, devido à sobrecarga da chamada delegada.

Se, no entanto, você estiver processando uma grande quantidade de dados e aplicando cálculos relativamente simples aos elementos, obterá um grande aumento de desempenho se:

  1. Você usa uma matriz para armazenar os dados.
  2. Você usa um loop for para acessar cada elemento (em oposição a foreach ou linq).

    • Nota: Quando o benchmarking, por favor, todos se lembrem – se você usar a mesma matriz / lista para dois testes consecutivos, o cache da CPU tornará o segundo mais rápido. *