Dicas de performance no .NET Core 3.1

A cada nova versão do .NET Core é possível ver que o time Microsoft e a comunidade colaboram muito no que diz respeito à otimizações e melhorias de performance. Neste artigo vou listar algumas dicas e configurações para turbinar ainda mais suas aplicações.

.NET é uma fantástica plataforma de desenvolvimento que nunca deixa de evoluir, tanto que a próxima versão (.NET 5), de acordo com o artigo do link abaixo, chegará bem mais performático e com melhorias significativas.

https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5

Enquanto essa versão não chega, vamos às dicas de performance no .NET Core 3.1:

1 – Mantenha os packages do nuget atualizados

Manter os packages da sua solução atualizados é uma boa estratégia para obter performance. Toda nova versão de um pacote traz novas features e melhorias, mas tenha muito cuidado, procure ler as notas sobre a nova versão se houve quebra de compatibilidade e sempre teste sua aplicação depois dessas atualizações.

Para atualizar os packages no Visual Studio, basta clicar no menu Tools => Nuget Package Manager => Manage Nuget Packages for Solution

Image for post


2 – Utilize a compactação de resposta

O .NET Coreconta com um middleware que otimiza o processo de compactação dos dados que são retornados pela aplicação. Em alguns casos é possível reduzir em mais de 50% o tamanho do objeto de retorno.

Para utilizar este recurso na sua aplicação basta configurar o AddResponseCompression UseResponseCompression no seu startup.cs conforme o exemplo abaixo:

Mais informações sobre compactação você confere no link abaixo:

https://docs.microsoft.com/pt-br/aspnet/core/performance/response-compression?view=aspnetcore-3.1

3 – Programe de forma assíncrona

O modelo de programação assíncrona foi introduzido no C # 5.0 e desde então tornou-se muito popular. O .NET Core usa o mesmo paradigma de programação assíncrona para tornar a aplicação mais confiável, rápida e responsiva.

Você deve usar a programação assíncrona de ponta a ponta no seu código.

Mais informações sobre programação assíncrona você confere no link abaixo:

https://docs.microsoft.com/pt-br/dotnet/csharp/programming-guide/concepts/async

4 – Não utilize “.Result” ou “.Wait()” em operações assíncronas

Uma maneira comum dos desenvolvedores contornarem a dificuldade de chamar métodos assíncronos a partir de métodos síncronos é utilizando a propriedade .Result ou o método .Wait(). A propriedade .Result aguarda a conclusão de uma tarefa e, em seguida, retorna seu resultado.

O código acima é exagerado, apenas para provar que é possível chamar funções assíncronas. É a pior coisa possível que você pode fazer, pois entrará em conflito, não importa em que contexto você está chamando, pois ele agenda tarefas para um conjunto de threads e em seguida bloqueia o segmento do conjunto de threads. Se chamado várias vezes em paralelo, esgotará o pool de threads e sua aplicação travará. Nesse caso, a melhor coisa que você pode fazer é reiniciar aplicação.

Mais detalhes sobre boas práticas em programação assíncrona você confere no link abaixo:

https://docs.microsoft.com/pt-br/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming

5 – Utilize o package Ben.BlockingDetector

Tem dificuldade de encontrar os bloqueios de threads da sua aplicação? Se sim, esse package te indica em quais lugares do seu código é preciso trabalhar corretamente as funções assíncronas, ajudando no processo de performance.

É muito simples de utilizar, basta incluir a linha app.UseBlockingDetection() no seu startup.cs e em todos os bloqueios de thread serão gerados warnings no seu console output do tipo Ben.Diagnostics.BlockingMonitor.

https://github.com/benaadams/Ben.BlockingDetector

6 – Utilize System.Text.Json ao invés do Newtonsoft.json

O ASP.NET Core 3.1 utiliza o System.Text.Json para serialização JSON por padrão. Agora é possível ler e gravar JSON de forma assíncrona, isso melhora o desempenho e o deixa melhor do que o package Newtonsoft.Json.

Para serializar um objeto, basta importar o namespace System.Text.Json e utilizar conforme o exemplo abaixo:

Você confere no link abaixo o teste feito entre os principais packages de serialização do .NET Core:

7 – Utilize o HttpClientFactory ao invés do HttpClient

Se sua aplicação precisa fazer chamadas externas para outras APIs, nunca utilize new HttpClient()isso causará um erro de esgotamento de sockets se chamado várias vezes seguida, o famoso SocketException.

HttpClientFactory resolve esse problema, gerenciando corretamente as instâncias do HttpClient e até definindo tempo de vida para reduzir o consumo de recursos.

Dicas de implementação do HttpClientFactory você confere aqui:

https://docs.microsoft.com/pt-br/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests

8 – Evite lançar exceções

Evite ao máximo lançar exceção do tipo:

  • throw new Exception(“Dados incorretos”);

Essa é a pior maneira de fazer validação e impacta diretamente na performance da sua aplicação. Um Exception deve ser tratado como um erro de código, uma falha.

Uma opção para o exemplo acima é aplicar o padrão Notification, que é utilizado para fazer validações do seu domínio.

Para entender melhor como utilizá-lo, acesse o link abaixo:

https://imasters.com.br/back-end/nao-lance-exceptions-em-seu-dominio-use-notifications

9 – Analise a telemetria das suas aplicações

Logs, você precisa de logs para entender como sua aplicação se comporta, quais métodos precisa otimizar, quais consultas do SQL precisa melhorar, quais exceções precisa trocar por notificações. Telemetria é o essencial para tomada de decisão no que diz respeito a performance.

Application Insighs e Elastic Stack são ótimas ferramentas de coleta de logs, em conjunto com o nuget package Serilog.

10 – Avalie e peça avaliação dos seus Pull Requests

Ajudar e ser ajudado no que diz respeito à código é uma evolução que nunca pode parar. Toda crítica de código, desde que tenha argumento, são muito bem vindas no processo de performance e otimização.

Para entender melhor como funciona o processo de Pull Request você encontra no link abaixo:

https://gomex.me/2020/07/05/precisamos-falar-sobre-pull-request/

11 – Mantenha seu código organizado

Isso mesmo, manter o código organizado também pode ser considerado um ganho de performance, pois é muito mais fácil otimizar a performance de um projeto com os códigos organizados, padronizados e bem escritos do que otimizar performance de um código “sujo” ou incompressível.

Há várias maneiras de escrever um código limpo, e você aprende isso no livro “Código Limpo”. Compre, leia e pratique!

Image for post

E para finalizar, veja o vídeo do Elemar Jrexplicando sobre as pequenas mudanças no código que geram grandes ganhos de performance.

Deixe uma resposta