Entenda aqui como o LINQ ficou tão poderoso no .net9

Posted by:

|

On:

|

Fala pessoal, como vocês estão?

Hoje estarei demonstrando as principais diferenças em termos de velocidade para o LINQ entre o .net8 e .net9.

Para isso iremos criar um projetinho benchmark para podermos testar algumas funções do LINQ e comparar a velocidade nas duas versões da plataforma .net;

Vamos começar?

Pré-requisitos

Antes de tudo você precisará ter as duas versões instaladas em sua maquina, abaixo irei deixar os links para downloads das duas versões:
.NET8: https://dotnet.microsoft.com/pt-br/download/dotnet/8.0
.NET9: https://dotnet.microsoft.com/pt-br/download/dotnet/9.0

Passo 1: Configurar o Projeto

Após isso iremos até um terminal ou através do VSCODE aberto em uma pasta pré-selecionada e iremos rodar o seguinte comando:

dotnet new console -n LinqBenchmarkApp

Com esse comando uma nova aplicação console irá ser criada e podemos acessar sua pasta também através do terminal com o seguinte comando:

cd LinqBenchmarkApp

Agora vamos adicionar o pacote de BenchmarkDotNet responsável por mensurar o desempenho da nossa aplicação.

dotnet add package BenchmarkDotNet

Após isso iremos criar uma classe responsável por centralizar nossos métodos e controlar os parâmetros de testes do benchmark.

Passo 2: Criar a Classe de Benchmark

Crie uma classe chamada LinqBenchmarks.cs na raiz do projeto com o seguinte conteúdo:

using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Running; using System.Collections.Generic; using System.Linq; namespace LinqBenchmarkApp { [SimpleJob(RuntimeMoniker.Net80, baseline: true)] [SimpleJob(RuntimeMoniker.Net90)] [HideColumns(“Job”, “Error”, “StdDev”, “Median”, “RatioSD”)] public class LinqBenchmarks { private List numbers; [Params(10, 100, 1000)] public int N; [GlobalSetup] public void Setup() { numbers = Enumerable.Range(1, N).ToList(); } [Benchmark] public int ListFind() { return numbers.Find(x => x == N); } [Benchmark] public int LinqFirstOrDefault() { return numbers.FirstOrDefault(x => x == N); } [Benchmark] public int LinqCount() { return numbers.Count(x => x > N / 2); } [Benchmark] public int ListCount() { int count = 0; foreach (var number in numbers) { if (number > N / 2) count++; } return count; } [Benchmark] public int LinqWhere() { return numbers.Where(x => x > N / 2).Count(); } } }

Como pode ver acima usamos algumas notations para definir o .net 8 como nosso framework base e o .net 9 como adicional, assim podemos comparar o desempenho dos métodos em ambas versões.


Feito isso, podemos chamar nossa classe de criada a partir da Program.cs, da seguinte maneira abaixo:

Passo 3: Modificar o Program.cs para Executar o Benchmark

No arquivo Program.cs, modifique o conteúdo para executar o benchmark:

using BenchmarkDotNet.Running; using LinqBenchmarkApp; var summary = BenchmarkRunner.Run();

Explicação do Código

  • BenchmarkDotNet.Attributes: Usamos atributos como [Benchmark], [GlobalSetup] e [Params] para configurar nossos benchmarks.
  • [Params(10, 100, 1000)]: Define os diferentes tamanhos de lista que queremos testar.
  • Setup(): Inicializa a lista numbers com uma sequência de números de 1 a N.
  • Métodos de Benchmark:
    • ListFind(): Usa o método Find da classe List<T>.
    • LinqFirstOrDefault(): Usa o método LINQ FirstOrDefault.
    • LinqCount(): Usa o método LINQ Count com uma condição.
    • ListCount(): Usa um loop foreach para contar elementos manualmente.
    • LinqWhere(): Usa Where seguido de Count para contar elementos que atendem à condição.

Passo 4: Executar o Benchmark

Execute o seguinte comando no terminal:

dotnet run -c Release

Nota: É importante executar em modo Release para que as otimizações do compilador sejam aplicadas.

Interpretação dos Resultados

Após a execução, o BenchmarkDotNet irá gerar um relatório semelhante a este:

Como você pode ver acima, em alguns casos o ganho de performance é muito expressivo, por exemplo no método LinqFirstOrDefault e LinqCount comprovando assim a eficiência e evolução que a Microsoft vem implementando nas novas versões do .NET.

Conclusão

Podemos concluir que as novas versões do .NET vêm aprimorando cada vez mais a velocidade e a eficiência do LINQ. Quem sabe o que o futuro nos reserva, não é mesmo?

Estou ansioso para ver as evoluções dessa tecnologia. Vamos juntos explorar essas novidades?