Como Rastrear Referências na Integração Contínua com o Bencher


A maioria dos resultados de benchmark são efêmeros. Eles desaparecem assim que seu terminal atinge o limite de rolagem. Alguns frameworks de benchmark permitem armazenar em cache os resultados, mas a maioria apenas os faz localmente. O Bencher permite que você acompanhe seus benchmarks tanto de execuções locais quanto de CI e compare os resultados, enquanto ainda utiliza seu framework de benchmark favorito.

Existem três maneiras populares de comparar resultados de benchmark quando Benchmarking Contínuo, ou seja, benchmarking em CI:

  • Benchmarking Contínuo Estatístico
    1. Acompanhe os resultados dos benchmarks ao longo do tempo para criar uma linha de base
    2. Use essa linha de base junto com Limiares Estatísticos para criar um limite estatístico
    3. Compare os novos resultados com esse limite estatístico para detectar regressões de desempenho
  • Benchmarking Contínuo Relativo
    1. Execute os benchmarks para o código da linha de base atual
    2. Alterne para a nova versão do código
    3. Execute os benchmarks para a nova versão do código
    4. Use Limiares Percentuais para criar um limite para o código da linha de base
    5. Compare os resultados da nova versão do código com os da linha de base para detectar regressões de desempenho
  • Detecção de Mudança de Ponto
    1. Ocasionalmente, execute os benchmarks para novas versões do código
    2. Use um algoritmo de detecção de mudança de ponto para detectar regressões de desempenho
    3. Faça bissecção para encontrar o commit que introduziu a regressão de desempenho

Benchmarking Contínuo Estatístico

Retomando de onde paramos nos tutoriais Início Rápido e Docker Auto-hospedado, vamos adicionar o Benchmarking Contínuo Estatístico ao nosso projeto Save Walter White.

🐰 Certifique-se de ter criado um token de API e definido como a variável de ambiente BENCHER_API_TOKEN antes de continuar!

Agora estamos prontos para executar nossos benchmarks no CI. Como cada ambiente de CI é um pouco diferente, o exemplo a seguir é mais ilustrativo do que prático. Para exemplos mais específicos, consulte Benchmarking Contínuo no GitHub Actions e Benchmarking Contínuo no GitLab CI/CD.

Primeiro, precisamos criar e manter uma linha de base histórica para nosso branch main ao realizar testes de benchmark a cada mudança no CI:

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--branch main \
--testbed ci-runner \
--threshold-measure latency \
--threshold-test t_test \
--threshold-max-sample-size 64 \
--threshold-upper-boundary 0.99 \
--thresholds-reset \
--err \
--adapter json \
bencher mock
  1. Use o subcomando CLI bencher run para rodar os benchmarks do seu branch feature-branch. Veja o subcomando CLI bencher run para uma visão geral completa. (ex: bencher run)
  2. Defina a opção --project para o slug do Projeto. Veja a documentação --project para mais detalhes. (ex: --project save-walter-white-1234abcd)
  3. Defina a opção --branch para o nome do branch base. Veja a documentação de --branch para uma visão geral completa. (ex: --branch main)
  4. Defina a opção --testbed para o nome do Testbed do corredor CI. Veja a documentação de --testbed para mais detalhes. (ex: --testbed ci-runner)
  5. Defina o Limite para o Branch main, Testbed ci-runner e Medida latency:
    1. Defina a opção --threshold-measure para a Medida latency incorporada que é gerada por bencher mock. Veja a documentação --threshold-measure para mais detalhes. (ex: --threshold-measure latency)
    2. Defina a opção --threshold-test para um teste t de Student (t_test). Veja a documentação --threshold-test para uma visão geral completa. (ex: --threshold-test t_test)
    3. Defina a opção --threshold-max-sample-size para o tamanho máximo da amostra de 64. Veja a documentação --threshold-max-sample-size para mais detalhes. (ex: --threshold-max-sample-size 64)
    4. Defina a opção --threshold-upper-boundary para o Limite Superior de 0.99. Veja a documentação --threshold-upper-boundary para mais detalhes. (ex: --threshold-upper-boundary 0.99)
    5. Configure o sinalizador --thresholds-reset para que apenas o Limite especificado esteja ativo. Veja a documentação --thresholds-reset para uma visão geral completa. (ex: --thresholds-reset)
  6. Defina o sinalizador --err para falhar o comando se um Alerta for gerado. Veja a documentação --err para uma visão geral completa. (ex: --err)
  7. Defina a opção --adapter para Bencher Metric Format JSON (json) que é gerado por bencher mock. Veja adapters de estrutura de benchmark para uma visão geral completa. (ex: --adapter json)
  8. Especifique os argumentos do comando de benchmark. Veja comando de benchmark para uma visão geral completa. (ex: bencher mock)

A primeira vez que esse comando é executado no CI, ele criará o Branch main se ainda não existir. O novo main não terá um ponto de início ou dados existentes. Um Limite será criado para o Branch main, Testbed ci-runner, e Medida latency. Em execuções subsequentes, novos dados serão adicionados ao Branch main. O Limite especificado será então usado para detectar regressões de desempenho.

Agora, estamos prontos para detectar regressões de desempenho no CI. É assim que acompanharíamos o desempenho de um novo branch de funcionalidades no CI, apropriadamente chamado feature-branch:

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--branch feature-branch \
--start-point main \
--start-point-hash 32aea434d751648726097ed3ac760b57107edd8b \
--start-point-clone-thresholds \
--start-point-reset \
--testbed ci-runner \
--err \
--adapter json \
bencher mock
  1. Use o subcomando CLI bencher run para rodar os benchmarks do seu branch feature-branch. Veja o subcomando CLI bencher run para uma visão geral completa. (ex: bencher run)
  2. Defina a opção --project para o slug do Projeto. Veja a documentação --project para mais detalhes. (ex: --project save-walter-white-1234abcd)
  3. Defina a opção --branch para o nome do Branch de funcionalidade. Veja a documentação de --branch para uma visão geral completa. (ex: --branch feature-branch)
  4. Configure o Ponto de Início para o Branch feature-branch:
    1. Defina a opção --start-point para o ponto de início do Branch de funcionalidades. Veja a documentação --start-point para uma visão geral completa. (ex: --start-point main)
    2. Defina a opção --start-point-hash para o git hash do ponto de início do Branch de funcionalidades. Veja a documentação --start-point-hash para uma visão geral completa. (ex: --start-point-hash 32ae...dd8b)
    3. Configure o sinalizador --start-point-clone-thresholds para clonar os Limites a partir do ponto de início. Veja a documentação --start-point-clone-thresholds para uma visão geral completa. (ex: --start-point-clone-thresholds)
    4. Configure o sinalizador --start-point-reset para sempre redefinir o Branch para o ponto de início. Isso evitará desvio de dados de benchmark. Veja a documentação --start-point-reset para uma visão geral completa. (ex: --start-point-reset)
  5. Defina a opção --testbed para o nome do Testbed. Veja a documentação de --tested para mais detalhes. (ex: --testbed ci-runner)
  6. Defina o sinalizador --err para falhar o comando se um Alerta for gerado. Veja a documentação --err para uma visão geral completa. (ex: --err)
  7. Defina a opção --adapter para Bencher Metric Format JSON (json) que é gerado por bencher mock. Veja adapters de estrutura de benchmark para uma visão geral completa. (ex: --adapter json)
  8. Especifique os argumentos do comando de benchmark. Veja comando de benchmark para uma visão geral completa. (ex: bencher mock)

A primeira vez que esse comando é executado no CI, Bencher criará o Branch feature-branch já que ele ainda não existe. O novo feature-branch usará o Branch main no hash 32aea434d751648726097ed3ac760b57107edd8b como seu ponto de início. Isso significa que o feature-branch terá uma cópia de todos os dados e Limites do Branch main para comparar os resultados de bencher mock. Em todas as execuções subsequentes, o Bencher irá redefinir o Branch feature-branch para o ponto de início, e usará os dados e Limites do Branch main para detectar regressões de desempenho.

Benchmarking Contínuo Relativo

Retomando de onde paramos nos tutoriais Início Rápido e Autohospedagem com Docker, vamos adicionar o Benchmarking Contínuo Relativo ao nosso projeto Save Walter White.

🐰 Certifique-se de criar um token de API e configurá-lo como a variável de ambiente BENCHER_API_TOKEN antes de continuar!

O Benchmarking Contínuo Relativo executa uma comparação lado a lado de duas versões do seu código. Isso pode ser útil ao lidar com ambientes CI/CD ruidosos, onde os recursos disponíveis podem variar bastante entre as execuções. Neste exemplo, vamos comparar os resultados da execução no branch main com os resultados da execução em um branch de feature, convenientemente chamado feature-branch. Como cada ambiente de CI é um pouco diferente, o exemplo a seguir é mais ilustrativo que prático. Para exemplos mais específicos, veja Benchmarking Contínuo em GitHub Actions e Benchmarking Contínuo em GitLab CI/CD.

Primeiro, precisamos fazer checkout do branch main com git no CI:

Terminal window
git checkout main

Depois, precisamos executar nossos benchmarks no branch main no CI:

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--branch feature-branch \
--start-point-reset \
--testbed ci-runner \
--adapter json \
bencher mock
  1. Use o subcomando da CLI bencher run para executar os benchmarks do seu branch main. Veja uma visão geral completa do subcomando bencher run da CLI. (ex: bencher run)
  2. Configure a opção --project para o slug do Projeto. Veja os documentos da opção --project para mais detalhes. (ex: --project save-walter-white-1234abcd)
  3. Configure a opção --branch para o nome do branch base. Veja uma visão geral completa dos documentos da opção --branch. (ex: --branch main)
  4. Configure o sinalizador --start-point-reset para sempre redefinir o branch base. Isso garantirá que todos os dados de benchmark sejam do runner do CI atual. Veja uma visão geral completa dos documentos do --start-point-reset. (ex: --start-point-reset)
  5. Configure a opção --testbed para o nome do Testbed do runner do CI. Veja os documentos da opção --testbed para mais detalhes. (ex: --testbed ci-runner)
  6. Configure a opção --adapter para Bencher Metric Format JSON (json) que é gerado por bencher mock. Veja uma visão geral completa dos adaptadores de harness de benchmark. (ex: --adapter json)
  7. Especifique os argumentos de comando do benchmark. Veja uma visão geral completa dos comandos de benchmark. (ex: bencher mock)

A primeira vez que este comando for executado no CI, ele criará o branch feature-branch já que ainda não existe. O novo feature-branch não terá um ponto de início, dados existentes ou Limiares. Nos execuções subsequentes, o Head antigo do feature-branch será substituído e um novo Head para o feature-branch será criado sem um ponto de início, dados existentes ou Limiares.

Em seguida, precisamos fazer checkout do branch feature-branch com git no CI:

Terminal window
git checkout feature-branch

Por fim, estamos prontos para executar nossos benchmarks de feature-branch no CI:

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--branch feature-branch \
--start-point main \
--start-point-reset \
--testbed ci-runner \
--threshold-measure latency \
--threshold-test percentage \
--threshold-upper-boundary 0.25 \
--thresholds-reset \
--err \
--adapter json \
bencher mock
  1. Use o subcomando da CLI bencher run para executar seus benchmarks de feature-branch. Veja uma visão geral completa do subcomando bencher run da CLI. (ex: bencher run)
  2. Configure a opção --project para o slug do Projeto. Veja os documentos da opção --project para mais detalhes. (ex: --project save-walter-white-1234abcd)
  3. Configure a opção --branch para o nome do branch de feature. Veja uma visão geral completa dos documentos da opção --branch. (ex: --branch feature-branch)
  4. Configure o Ponto de Início para o branch feature-branch:
    1. Configure a opção --start-point para o ponto de início do branch de feature. Veja uma visão geral completa dos documentos do --start-point. (ex: --start-point main)
    2. Configure o sinalizador --start-point-reset para sempre redefinir o branch para o ponto de início. Isso usará apenas os resultados mais recentes do benchmark relativo. Veja uma visão geral completa dos documentos do --start-point-reset. (ex: --start-point-reset)
  5. Configure a opção --testbed para o nome do Testbed do runner do CI. Veja os documentos da opção --testbed para mais detalhes. (ex: --testbed ci-runner)
  6. Configure o Limite para o branch feature-branch, Testbed ci-runner e Medida latency:
    1. Configure a opção --threshold-measure para a Medida latency incorporada que é gerada por bencher mock. Veja mais detalhes dos documentos da opção --threshold-measure. (ex: --threshold-measure latency)
    2. Configure a opção --threshold-test para uma porcentagem básica (percentage). Veja uma visão geral completa dos documentos da opção --threshold-test. (ex: --threshold-test percentage)
    3. Configure a opção --threshold-upper-boundary para o Limite Superior de 0.25. Veja mais detalhes dos documentos da opção --threshold-upper-boundary. (ex: --threshold-upper-boundary 0.25)
    4. Configure o sinalizador --thresholds-reset para que apenas o Limite especificado fique ativo. Veja uma visão geral completa dos documentos do --thresholds-reset. (ex: --thresholds-reset)
  7. Configure o sinalizador --err para falhar o comando se um Alerta for gerado. Veja uma visão geral completa dos documentos do --err. (ex: --err)
  8. Configure a opção --adapter para Bencher Metric Format JSON (json) que é gerado por bencher mock. Veja uma visão geral completa dos adaptadores de harness de benchmark. (ex: --adapter json)
  9. Especifique os argumentos de comando do benchmark. Veja uma visão geral completa dos comandos de benchmark. (ex: bencher mock)

Toda vez que este comando for executado no CI, ele estará comparando os resultados do feature-branch com apenas os resultados mais recentes do main. O Limite especificado é então usado para detectar regressões de desempenho.

Detecção de Punto de Mudança

A Detecção de Punto de Mudança usa um algoritmo de ponto de mudança para avaliar uma grande janela de resultados recentes. Isso permite que o algoritmo ignore outliers como ruído e produza menos falsos positivos. Embora a Detecção de Punto de Mudança seja considerada benchmarking contínuo, ela não permite detectar regressão de desempenho em CI. Ou seja, você não pode detectar uma regressão de desempenho antes de um branch de feature ser mesclado. Isso é algumas vezes referido como detecção “fora de banda”.

Por exemplo, se você tem um benchmark bench_my_critical_path, e ele teve as seguintes latências históricas: 5 ms, 6 ms, 5 ms, 5ms, 7ms.

Se o próximo resultado do benchmark fosse 11 ms, então um limite de Benchmarking Contínuo Estatístico e o algoritmo de Detecção de Punto de Mudança interpretariam as coisas de maneira muito diferente. O limite provavelmente seria excedido e um alerta seria gerado. Se essa execução do benchmark estivesse vinculada a um pull request, a build provavelmente seria configurada para falhar devido a esse alerta. No entanto, o algoritmo de ponto de mudança não faria nada… ainda. Se na próxima execução as coisas caíssem de volta para 5 ms, provavelmente não geraria um alerta. Por outro lado, se na próxima ou duas próximas rodadas resultassem em 10 ms e 12 ms, somente então o algoritmo de ponto de mudança acionaria um alerta.

Você está interessado em usar Detecção de Punto de Mudança com Bencher? Se sim, por favor, deixe um comentário na issue de acompanhamento ou entre em contato diretamente conosco.



🐰 Parabéns! Você aprendeu como rastrear referências na Integração Contínua com o Bencher! 🎉


Adicionar o Bencher ao GitHub Actions ➡

Adicionar o Bencher ao GitLab CI/CD ➡

🤖 Este documento foi gerado automaticamente pelo OpenAI GPT-4. Pode não ser preciso e pode conter erros. Se você encontrar algum erro, abra um problema no GitHub.


Published: Fri, October 27, 2023 at 8:40:00 AM UTC | Last Updated: Sat, October 12, 2024 at 12:45:00 PM UTC