BenchmarkDotNet: Medindo a performance de código .NET

Neste artigo vou apresentar a biblioteca BenchmarkDotNet, e como você pode medir performance de códigos utilizando ela, resultando em conjuntos de resultados de execuções e dados relacionados a sua performance.

Mas antes de avançarmos…

Antes de avançarmos no artigo e apresentar a biblioteca BenchmarkDotNet, é essencial entender alguns fundamentos relacionados a performance em códigos.

Primeiramente, se não se mede, não se tem como afirmar com segurança se estamos ou não com problemas de performance. E junto a isso, é necessário ter uma base de comparação, com uma métrica clara utilizada. Vamos usar tempo de resposta? De qual carga estamos falando? Aí entram também conceitos como escalabilidade, mas não vamos discutir neste artigo.

Além disso, falando de aplicações .NET, existem múltiplas camadas de otimização de performance. São elas, e estão na ordem de prioridade na performance:

  • Arquitetura
  • Algoritmos
  • Framework .NET
  • CLR
  • Código Assembly

No dia a dia, na maior parte do tempo, falamos de performance a nível de Algoritmos, já que é a primeira coisa que verificamos quando percebemos que algo não está indo bem a nível de performance. Nos perguntamos algumas coisas como:

  • Estou realizando trabalho desnecessário aqui? Talvez um nível maior na complexidade por conta de uma estrutura de repetição?
  • Será que estou indo no banco de dados algumas vezes desnecessariamente? Será possível ser mais eficiente na consulta?
  • Preciso mesmo dessa coleção adicional aqui? Não seria possível realizar as operações in-place?

Caso queira aprender bastante sobre performance em código .NET, eu indico o livro Writing High-Performance .NET Code, do Ben Watson, que é Principal Software Engineer na Microsoft. Clique aqui para adquirir o livro em Kindle ou Físico na Amazon.

Bom, com esse conceitos introdutórios em mente, podemos avançar.

O que é o BenchmarkDotNet

BenchmarkDotNet uma biblioteca que permite gerar benchmarks a partir de métodos, apresentando resultados de performance com boa usabilidade.

Ela é apoiada pelo .NET Foundation, e é utilizada por mais de 11700 projetos, incluindo o próprio .NET Runtime!

Para instalar no seu projeto basta buscar pelo pacote BenchmarkDotNet utilizando o Gerenciador de Pacotes do NuGet ou executar o comando abaixo com a linha de comando do .NET.

dotnet add package BenchmarkDotNet

Vamos ver na prática?

Para o exemplo prático, vai ser realizada uma análise de performance entre as diferentes formas de comparação de strings. Os métodos de comparação utilizados são:

  • Igualdade com ToUpper
  • Igualdade com ToLower
  • Equals com IgnoreCase
  • Compare com IgnoreCase

Essa é uma operação que a performance pode variar consideravelmente entre o método utilizado, potencialmente afetando de forma significativa em cenários de alto número de comparações (como buscas em coleções).

A classe que contém os benchmarks está logo abaixo.

using BenchmarkDotNet.Attributes;

namespace PerformanceBenchmark
{
    public class ComparacaoStringBenchmarks
    {
        public string nomeV1 = "LuisDev";
        public string nomeV2 = "lUISdEV";

        [Benchmark]
        public bool IgualdadeComToLower() {
            return nomeV1.ToLower() == nomeV2.ToLower();
        }

        [Benchmark]
        public bool IgualdadeComToUpper() {
            return nomeV1.ToUpper() == nomeV2.ToUpper();
        }

        [Benchmark]
        public bool CompareComIgnoreCase() {
            return string.Compare(nomeV1, nomeV2, StringComparison.OrdinalIgnoreCase) == 0;
        }

        [Benchmark]
        public bool EqualsIgnoreCase() {
            return nomeV1.Equals(nomeV2, StringComparison.OrdinalIgnoreCase);
        }
    }
}

Sobre o código acima, note o uso das anotações [Benchmark]. Através delas o BenchmarkDotNet vai realizar a comparação da performance de suas execuções.

Como estamos em um projeto Console, basta agora alterarmos o arquivo Program.cs para poder executar os benchmarks.

using BenchmarkDotNet.Running;
using PerformanceBenchmark;

var summary = BenchmarkRunner.Run<ComparacaoStringBenchmarks>();

E finalmente, executar a aplicação em configuração Release.

dotnet run –configuration Release

Com isso, começarão a ser exibidas mensagens mostrando os passos sendo executadas para a geração dos benchmarks.

Benchmark de Performance com BenchmarkDotNet

Existem outras saídas além dessas, mas para ser objetivo coloquei as mais importantes relacionadas ao resultado final.

Com isso, vemos que na ordem de performance, da melhor para a pior, estão:

  • Equals com IgnoreCase
  • Compare com IgnoreCase
  • Igualdade com ToUpper, Igualdade com ToLower

Da mesma forma, dá para realizar comparações entre diversos métodos que queira comparar a performance.


Quer alavancar sua carreira como Desenvolvedor(a) .NET?

Além de Desenvolvedor .NET Sênior, eu sou instrutor de mais de 700 alunos e também tenho dezenas de mentorados.

Conheça o Método .NET Direto ao Ponto, minha plataforma com mais de 800 videoaulas, com cursos cobrindo temas relacionados a linguagem C# e Programação Orientada a Objetos, APIs REST com ASP NET Core, Microsserviços com ASP NET Core, HTML, CSS e JavaScript, Desenvolvimento Front-end com Angular, Desenvolvimento Front-end com React, JavaScript Intermediário, TypeScript, Formação Arquitetura de Software, Microsoft Azure, Agile, SQL, e muito mais.

Inclui comunidade de centenas de alunos, suporte por ela, plataforma e e-mail, atualizações regulares e muito mais.

Clique aqui para ter mais informações e garantir sua vaga


Conclusão

Neste artigo foram apresentados conceitos relacionados a performance, bem como a biblioteca BenchmarkDotNet e como realizar um benchmark de performance de diferentes abordagens de comparação de string.

Compartilhe com seus colegas e amigos da área!