NET 8 - Melhorando o desempenho com CompositeFormat


 Hoje vou apresentar o novo recurso disponível a partir do .NET 8 relacionado à formatação de strings chamado CompositeFormat.

Desde o seu início, a plataforma .NET forneceu vários métodos para formatação de strings, sendo string.Format a ferramenta principal.

No entanto, esse método tinha suas desvantagens, como a necessidade de analisar a sequência de formato composto em cada chamada e as alocações de boxing para tipos de valor. Essa abordagem, embora funcional, não foi otimizada para desempenho, especialmente em cenários onde a string de formato não muda entre as invocações.

O C# 6 introduziu a interpolação de strings como um açúcar sintático, simplificando a maneira como os desenvolvedores podiam concatenar strings e expressões. Melhorada ainda mais no .NET 6 e no C# 10, a interpolação de strings moveu a análise para o tempo de compilação, reduzindo significativamente a sobrecarga do tempo de execução e eliminando a necessidade de alocações de boxing. Este foi um avanço considerável, mas teve sua limitação: a string de formato precisava ser conhecida em tempo de compilação.

Os aplicativos do mundo real geralmente exigem formatação dinâmica de strings, onde as strings de formato são conhecidas apenas em tempo de execução, como aquelas extraídas de arquivos de recursos ou configurações externas. Nesses casos, string.Format permaneceu a única opção, até agora.

Apresentando CompositeFormat

O .NET 8 apresenta a classe CompositeFormat, que traz a eficiência da análise em tempo de compilação para cenários de tempo de execução. Ele permite analisar uma string de formato composto uma vez e reutilizar a instância CompositeFormat várias vezes.

Essa abordagem melhora significativamente o desempenho, especialmente em cenários onde a cadeia de caracteres de formato é dinâmica, mas usada repetidamente.

Para avaliar o desempenho entre CompositeFormat e string.Format vamos usar um projeto console criado no .NET 8 com o seguinte código:
 
using BenchmarkDotNet.Attributes;
using
BenchmarkDotNet.Running;
using
System.Text;

var resultado = BenchmarkRunner.Run<CompositeFormatVsStringFormat>();

Console.ReadLine();

[MemoryDiagnoser]
public
class CompositeFormatVsStringFormat
{
 
private static readonly CompositeFormat composite_format =
                CompositeFormat.Parse(TempoVida.HoraAtual);

  [Benchmark(Baseline = true)]
 
public string FormatString() =>
                string
.Format(null, TempoVida.HoraAtual, DateTime.Now, 10);
 
  [Benchmark]
 
public string FormatComposite() =>
                string
.Format(null, composite_format, DateTime.Now, 10);
}

internal static class TempoVida
{
 
public static string HoraAtual =>
                      
"A hora atual é {0:t}. Minha idade é : {1}";
}

Executando o projeto obtemos o seguinte resultado :

A avaliação comparativa da nova abordagem revela as suas vantagens.

Uma comparação entre o método FormatString tradicional e o novo método FormatComposite mostra uma melhoria notável no tempo de execução e uma redução na alocação de memória.

A classe CompositeFormat é particularmente benéfica em cenários onde as strings de formato são geradas ou buscadas dinamicamente em tempo de execução, mas usadas repetidamente.

Isso pode incluir estruturas de registro em log, manipulação de cadeias de caracteres localizadas ou qualquer situação em que as cadeias de formato variem com base nas condições de tempo de execução.

É essencial equilibrar o custo inicial de análise da sequência de formato composto em relação aos benefícios de desempenho obtidos com o uso repetido.

A introdução do CompositeFormat no .NET 8 é uma prova da evolução contínua da estrutura .NET, adaptando-se continuamente às necessidades do desenvolvimento de software moderno.

Ao abordar uma limitação importante na formatação de strings, o CompositeFormat abre novos caminhos para otimizar o desempenho em aplicativos .NET, e, como desenvolvedores, agora temos mais uma ferramenta poderosa à nossa disposição, capacitando-nos a escrever códigos mais eficientes e com melhor desempenho.

E estamos conversados...

"No dia seguinte João viu a Jesus, que vinha para ele, e disse: Eis o Cordeiro de Deus, que tira o pecado do mundo."
João 1:29

Referências:


José Carlos Macoratti