Programação e desenvolvimento de software

As melhorias do .NET 11 acumulam ganhos de desempenho, do JIT à programação assíncrona

A Microsoft apresenta centenas de melhorias no .NET 11, com foco claro no compilador JIT, na redução de alocações e na melhoria das chamadas de interfaces e delegados, além da estrutura interna de async/await. Os resultados publicados mostram que os ganhos vêm da remoção de verificações, alocações e chamadas desnecessárias, e não de uma única grande mudança.

2026-09-15
6 min de leitura
6 visualizações
فريق تحرير certi.news
As melhorias do .NET 11 acumulam ganhos de desempenho, do JIT à programação assíncrona

A Microsoft apresenta, em uma publicação no .NET Blog datada de 15 de setembro de 2026, centenas de melhorias que chegaram ao .NET 11, descrevendo-as como o resultado cumulativo de um trabalho que envolveu o compilador Just-In-Time (JIT), o runtime e as bibliotecas. A ideia principal não é a existência de um recurso isolado que multiplique o desempenho, mas a remoção de pequenos ganhos recorrentes: uma verificação de limites que deixou de ser necessária, uma alocação de memória eliminada, um bloqueio ou uma chamada ao sistema evitada e loops que passaram a ser executados com menos ciclos do processador.

A importância desse tipo de melhoria é que grande parte dele não exige alterações no código das aplicações nem seu redesenho. O compilador JIT transforma o IL intermediário, normalmente produzido por C#, F# e Visual Basic, em instruções nativas executadas pelo processador. Quando consegue provar que uma chamada virtual pode ser direcionada a um tipo específico, ou que determinada verificação não falhará, ele pode produzir instruções mais curtas e aumentar as chances de incorporar funções umas às outras.

Melhoria da remoção de abstrações

Uma parte importante do material concentra-se no que a Microsoft chama de remoção de abstrações, ou seja, permitir que o runtime ignore o custo de execução de algumas abstrações necessárias ao desenvolvedor no projeto do programa. Exemplos incluem chamadas de interfaces e funções virtuais, nas quais a execução tradicional pode precisar carregar vários ponteiros e realizar uma chamada indireta, impedindo a incorporação da função chamada à função atual.

O .NET 11 continua desenvolvendo a técnica de “desvirtualização protegida”, ou Guarded Devirtualization. O JIT identifica o tipo mais comum durante a execução, cria um caminho rápido para chamá-lo diretamente e mantém o caminho virtual para garantir a correção da execução caso outro tipo apareça posteriormente. Quando isso permite incorporar a função, outras melhorias tornam-se possíveis, como a propagação de constantes, a remoção de ramificações e de verificações de limites.

O trabalho se estende a funções virtuais genéricas, às operações ReadyToRun e NativeAOT e às implementações virtuais padrão em interfaces. O material indica que essas melhorias podem aumentar o tamanho do código quando as chamadas diretas levam a mais incorporações, mas tornam a lógica do programa mais visível para o otimizador.

Menos alocações e menor impacto sobre o coletor de lixo

O .NET 11 também continua ampliando a análise de escape, ou Escape Analysis, que tenta determinar se um objeto criado dentro de uma função ultrapassa seu escopo. Se for comprovado que ele não sai desse escopo, o JIT poderá evitar colocá-lo no heap gerenciado ou eliminar completamente a alocação em alguns casos, reduzindo a pressão sobre o coletor de lixo.

A fonte apresenta exemplos de melhoria no boxing de valores anuláveis, ou Nullable boxing, e na análise condicional de escape em enumerações de coleções. Em uma das medições, uma alocação de 32 bytes desapareceu ao enumerar uma coleção criada a partir de um campo de instância, e o tempo de execução caiu de 13,874 nanossegundos no .NET 10 para 2,674 nanossegundos no .NET 11. Algumas situações que usam valores genéricos ou chamadas de interfaces também passaram a evitar alocações temporárias de 24 bytes.

Esses números dizem respeito a operações muito pequenas e, portanto, não devem ser interpretados como um aumento geral e constante no desempenho de toda aplicação. Seu principal benefício é revelar padrões de código que o runtime consegue otimizar, enquanto o impacto efetivo dependerá da natureza da aplicação e de seus caminhos críticos.

Delegados e runtime assíncrono

O .NET 11 inclui alterações na representação de delegados no CoreCLR, entre elas a remoção de um campo do tamanho de um ponteiro de cada objeto delegado em um processo de 64 bits, o que representa uma economia de 8 bytes por delegado, segundo o material. Os campos da representação de delegados também foram reorganizados no NativeAOT, e alguns valores usados em conjunto foram posicionados na memória para melhorar o acesso a eles em arquiteturas como Arm64.

A publicação também apresenta uma nova estrutura chamada “runtime async”, que transfere parte da responsabilidade pela transformação de métodos async/await do compilador C# para o JIT e o runtime. No modelo tradicional, o compilador cria uma máquina de estados contendo os campos necessários para a retomada, como parâmetros, variáveis locais, awaiters e o estado da execução. Já o novo modelo depende de um contrato menor no IL e deixa para o runtime e o JIT decisões relacionadas ao que permanece vivo nos pontos de suspensão, à forma de organizar os objetos de continuação e à criação de Task ou ValueTask visível externamente.

O que muda na prática?

O significado editorial desta rodada é que o .NET 11 aposta mais na melhoria do código existente do que na adição de novas APIs. Aplicações que dependem intensamente de interfaces, funções genéricas, delegados, enumeração e operações assíncronas podem se beneficiar sem alterações diretas no código-fonte, mas o nível de melhoria variará conforme o processador, o sistema operacional, as configurações do runtime e a natureza da carga de trabalho.

A Microsoft recomenda testar os resultados usando o BenchmarkDotNet, instalando o .NET 10 e o .NET 11 e executando o mesmo código nas duas versões. Ela alerta que as medições publicadas são testes muito precisos e podem ser afetadas pelo hardware, por outros processos e pelas configurações do ambiente. Portanto, os resultados de um teste pequeno não são suficientes para tomar uma decisão de atualização ou comprovar uma melhoria abrangente; é necessário medir as cargas de trabalho reais da aplicação antes de adotar conclusões mais amplas.

Fonte da notícia
ف
Autor

فريق تحرير certi.news

Na mesma categoria

Você também pode gostar

Ver todas as notícias