Início Rápido


O que é o Bencher?

Bencher é um conjunto de ferramentas de execução contínua de benchmark. Você já teve um problema de performance que impactou seus usuários? O Bencher poderia ter impedido que isso acontecesse. O Bencher permite que você detecte e evite problemas de performance antes que cheguem à produção.

  • Executar: Execute seus benchmarks localmente ou no CI usando suas ferramentas favoritas. O CLI bencher simplesmente encapsula seu harness de benchmark existente e armazena seus resultados.
  • Acompanhar: Acompanhe os resultados dos seus benchmarks ao longo do tempo. Monitore, consulte e crie gráficos dos resultados usando o console web do Bencher, baseado na branch de origem, testbed e tipo de métrica.
  • Capturar: Capture regressões de performance no CI. O Bencher usa análises avançadas e personalizáveis para detectar regressões de performance antes que elas cheguem à produção.

Pelos mesmos motivos que os testes unitários são executados no CI para prevenir regressões de recursos, benchmarks devem ser executados no CI com o Bencher para prevenir regressões de performance. Bugs de performance são bugs!


Instale o CLI bencher

Para instalar o CLI bencher, você precisará ter o cargo instalado. Verifique se você tem o cargo instalado.

Execute: cargo --version

Você deve ver algo como:

$ cargo --version
cargo 1.65.0 (4bc8f24d3 2022-10-20)

Está tudo bem se o seu número de versão for diferente. É apenas importante que esse comando funcionar. Se não, siga as instruções para instalar o cargo via rustup.

No Linux ou macOS, execute:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Com o cargo instalado, podemos instalar o CLI bencher.

Execute:

cargo install --git https://github.com/bencherdev/bencher --tag v0.3.18 --locked bencher_cli

Você dever ver algo como:

$ cargo install --git https://github.com/bencherdev/bencher --tag 0.3.18 --locked bencher_cli
  Installing bencher_cli v0.3.18 (/workspace/bencher/services/cli)
    Updating crates.io index

    Finished release [optimized] target(s) in 0.27s
  Installing /workspace/.cargo/bin/bencher
   Installed package `bencher_cli v0.3.18 (/workspace/bencher/services/cli)` (executable `bencher`)

Novamente, não tem problema se a saída for diferente. O importante é que esse comando funcione.


Finalmente, vamos testar se temos o CLI bencher instalado.

Execute: bencher --version

Você deve ver:

$ bencher —version
bencher 0.3.18

Crie uma conta no Bencher Cloud

O Bencher é open source e pode ser hospedado por você mesmo. Se você estiver interessado em auto-hospedagem, confira o tutorial do Bencher Docker. Para este tutorial, no entanto, vamos usar o Bencher Cloud.

Inscreva-se para o Bencher Cloud


Depois de criar uma conta, você precisará confirmar seu endereço de e-mail. Verifique seu e-mail para encontrar um link de confirmação. Depois disso, você deve estar logado no Bencher Cloud.


Crie um Token da API

Para usar a API do Bencher, você precisará criar um token da API. Navegue até o Console do Bencher. Passe o mouse sobre o seu nome no canto superior direito. Um menu dropdown deve aparecer. Selecione Tokens. Uma vez na página Tokens da API, clique no botão ➕ Add.

Adicionar um Token da API


Depois de criar seu novo token da API, você precisará copiá-lo para a área de transferência. No terminal que você planeja trabalhar, exporte o token da API como uma variável de ambiente.

Execute: export BENCHER_API_TOKEN=SEU_TOKEN

Se você executar: echo $BENCHER_API_TOKEN

Você deve ver:

$ echo $BENCHER_API_TOKEN
SEU_TOKEN

🐰 Nota: Se você mudar para um terminal diferente, precisará exportar o token da API novamente.


Crie um Projeto

Agora que temos uma conta de usuário e um token da API, podemos criar um Projeto. Primeiro, precisamos saber a qual organização nosso novo projeto pertencerá.

Execute: bencher org ls

You should see something like:

$ bencher org ls
[
  {
    "name": "Saul Goodman",
    "slug": "saul-goodman",
    "uuid": "4581feb0-6cac-40a9-bd8a-d7865183b01e"
    "created": "2022-07-06T11:24:36Z",
    "modified": "2022-07-06T11:24:36Z"
  }
]

Sua saída deve ser ligeiramente diferente da acima:

  • O uuid é pseudoaleatório
  • O name e slug serão baseados em seu nome de usuário
  • Os timestamps created e modified serão de quando você acabou de se inscrever

Agora podemos criar um novo Projeto dentro de sua Organização. Substitua seu slug da Organização pelo argumento --org (ou seja, SEU_ORG_SLUG) no comando abaixo.

Execute: bencher project create --org SEU_ORG_SLUG --url http://www.savewalterwhite.com "Save Walter White"

Você deve ver algo como:

$ bencher project create --org saul-goodman --url http://www.savewalterwhite.com "Save Walter White"
{
  "organization": "4581feb0-6cac-40a9-bd8a-d7865183b01e",
  "name": "Save Walter White",
  "slug": "save-walter-white-12345",
  "uuid": "c6c2a8e8-685e-4413-9a19-5b79053a71b1"
  "url": "http://www.savewalterwhite.com",
  "public": true,
  "created": "2022-07-06T11:36:24Z",
  "modified": "2022-07-06T11:36:24Z"
}

Novamente, sua saída deve ser ligeiramente diferente da acima. É apenas importante que esse comando funcione. Anote o campo slug do Projeto (ou seja, save-walter-white-12345).


Execute um Relatório

Finalmente estamos prontos para coletar algumas métricas de benchmark! Para simplificar, vamos usar dados fictícios neste tutorial.

Execute: bencher mock

Você deverá ver algo como:

$ bencher mock
{
  "bencher::mock_0": {
    "latency": {
      "value": 3.7865423396154463,
      "lower_value": 3.4078881056539014,
      "upper_value": 4.165196573576991
    }
  },
  "bencher::mock_1": {
    "latency": {
      "value": 16.398332128878437,
      "lower_value": 14.758498915990593,
      "upper_value": 18.03816534176628
    }
  },
  "bencher::mock_2": {
    "latency": {
      "value": 20.88091359871672,
      "lower_value": 18.792822238845048,
      "upper_value": 22.969004958588393
    }
  },
  "bencher::mock_3": {
    "latency": {
      "value": 33.88103801203782,
      "lower_value": 30.492934210834036,
      "upper_value": 37.2691418132416
    }
  },
  "bencher::mock_4": {
    "latency": {
      "value": 40.90515638867921,
      "lower_value": 36.81464074981129,
      "upper_value": 44.99567202754713
    }
  }
}

Sua saída deve ser ligeiramente diferente da acima, pois os dados são pseudoaleatórios. É apenas importante que esse comando funcione.


Agora vamos executar um relatório usando dados fictícios de métricas de benchmark. Substitua seu slug do Projeto pelo argumento --project (ou seja, SEU_PROJECT_SLUG) no comando abaixo.

Execute: bencher run --project SEU_PROJECT_SLUG "bencher mock"

Você deverá ver algo como:

$ bencher run --project save-walter-white-12345 "bencher mock"
{
  "bencher::mock_0": {
    "latency": {
      "value": 0.15496641529475275,
      "lower_value": 0.13946977376527747,
      "upper_value": 0.17046305682422802
    }
  },
  "bencher::mock_1": {
    "latency": {
      "value": 18.648298578180437,
      "lower_value": 16.783468720362393,
      "upper_value": 20.513128435998482
    }
  },
  "bencher::mock_2": {
    "latency": {
      "value": 28.20328182167366,
      "lower_value": 25.382953639506294,
      "upper_value": 31.023610003841025
    }
  },
  "bencher::mock_3": {
    "latency": {
      "value": 34.45732560787596,
      "lower_value": 31.01159304708836,
      "upper_value": 37.903058168663556
    }
  },
  "bencher::mock_4": {
    "latency": {
      "value": 44.9237520767597,
      "lower_value": 40.43137686908373,
      "upper_value": 49.41612728443567
    }
  }
}

{
  "branch": "master",
  "end_time": "2023-07-18T14:21:27.796871Z",
  "results": [
    "{\n  \"bencher::mock_0\": {\n    \"latency\": {\n      \"value\": 0.15496641529475275,\n      \"lower_value\": 0.13946977376527747,\n      \"upper_value\": 0.17046305682422802\n    }\n  },\n  \"bencher::mock_1\": {\n    \"latency\": {\n      \"value\": 18.648298578180437,\n      \"lower_value\": 16.783468720362393,\n      \"upper_value\": 20.513128435998482\n    }\n  },\n  \"bencher::mock_2\": {\n    \"latency\": {\n      \"value\": 28.20328182167366,\n      \"lower_value\": 25.382953639506294,\n      \"upper_value\": 31.023610003841025\n    }\n  },\n  \"bencher::mock_3\": {\n    \"latency\": {\n      \"value\": 34.45732560787596,\n      \"lower_value\": 31.01159304708836,\n      \"upper_value\": 37.903058168663556\n    }\n  },\n  \"bencher::mock_4\": {\n    \"latency\": {\n      \"value\": 44.9237520767597,\n      \"lower_value\": 40.43137686908373,\n      \"upper_value\": 49.41612728443567\n    }\n  }\n}\n"
  ],
  "settings": {},
  "start_time": "2023-07-18T14:21:27.773930Z",
  "testbed": "base"
}
{
  "uuid": "5554a92c-6f5c-481d-bd47-990f0a9bac6d",
  "user": { ... },
  "project": { ... },
  "branch": { ... },
  "testbed": { ...},
  "start_time": "2023-07-18T14:21:27Z",
  "end_time": "2023-07-18T14:21:27Z",
  "adapter": "magic",
  "results": [
    [
      {
        "metric_kind": { ... },
        "threshold": null,
        "benchmarks": [ ... ]
      }
    ]
  ],
  "alerts": [],
  "created": "2023-07-18T14:21:27Z"
}

View results:
- bencher::mock_0: https://bencher.dev/console/projects/save-walter-white-12345/perf?metric_kinds=4358146b-b647-4869-9d24-bd22bb0c49b5&branches=95521eff-09fa-4c02-abe1-dd824108869d&testbeds=5b4a6f3e-a27d-4cc3-a2ce-851dc6421e6e&benchmarks=88375e7c-f1e0-4cbb-bde1-bdb7773022ae
- bencher::mock_1: https://bencher.dev/console/projects/save-walter-white-12345/perf?metric_kinds=4358146b-b647-4869-9d24-bd22bb0c49b5&branches=95521eff-09fa-4c02-abe1-dd824108869d&testbeds=5b4a6f3e-a27d-4cc3-a2ce-851dc6421e6e&benchmarks=e81c7863-cc4b-4e22-b507-c1e238871137
- bencher::mock_2: https://bencher.dev/console/projects/save-walter-white-12345/perf?metric_kinds=4358146b-b647-4869-9d24-bd22bb0c49b5&branches=95521eff-09fa-4c02-abe1-dd824108869d&testbeds=5b4a6f3e-a27d-4cc3-a2ce-851dc6421e6e&benchmarks=31dede44-d23a-4baf-b639-63f2ac742e42
- bencher::mock_3: https://bencher.dev/console/projects/save-walter-white-12345/perf?metric_kinds=4358146b-b647-4869-9d24-bd22bb0c49b5&branches=95521eff-09fa-4c02-abe1-dd824108869d&testbeds=5b4a6f3e-a27d-4cc3-a2ce-851dc6421e6e&benchmarks=c7e32369-f3dd-473d-99a3-6289ae32b38e
- bencher::mock_4: https://bencher.dev/console/projects/save-walter-white-12345/perf?metric_kinds=4358146b-b647-4869-9d24-bd22bb0c49b5&branches=95521eff-09fa-4c02-abe1-dd824108869d&testbeds=5b4a6f3e-a27d-4cc3-a2ce-851dc6421e6e&benchmarks=779bc477-4964-4bae-aa8c-4da3e388822c

Agora você pode ver os resultados de cada um dos benchmarks no navegador. Clique ou copie e cole os links de View results. Deve haver apenas um único ponto de dados para cada benchmark, então vamos adicionar mais dados!


Primeiro, vamos definir nosso slug do Projeto como uma variável de ambiente, para que não precisemos fornecê-lo com o --project em cada execução.

Execute: export BENCHER_PROJECT=save-walter-white-12345

Se você executar: echo $BENCHER_PROJECT

Você deve ver:

$ echo $BENCHER_PROJECT
save-walter-white-12345

Vamos executar o mesmo comando novamente sem --project para gerar mais dados.

Execute: bencher run "bencher mock"


Agora, vamos gerar mais dados, mas desta vez vamos canalizar nossos resultados para bencher run.

Execute: bencher mock | bencher run


Às vezes, você pode querer salvar seus resultados em um arquivo e ter o bencher run buscá-los.

Execute: bencher run "bencher mock > results.json" --file results.json


Da mesma forma, você pode ter um processo separado para executar seus benchmarks e salvar seus resultados em um arquivo. Então bencher run apenas os pegará.

Execute: bencher mock > results.json && bencher run --file results.json


Finalmente, vamos preencher muitos dados usando o argumento --iter de bencher run.

Execute: bencher run --iter 16 "bencher mock"


🐰 Dica: Confira a documentação do subcomando bencher run CLI para uma visão completa de tudo que bencher run pode fazer!


Gerar um Alerta

Agora que temos alguns dados históricos para nossos benchmarks, vamos gerar um Alerta! Os alertas são gerados quando o resultado de um benchmark é considerado uma regressão de desempenho. Então, vamos simular uma regressão de desempenho!

Execute: bencher run "bencher mock --pow 8"


Deve haver uma nova seção no final da saída chamada View alerts:

View alerts:
- bencher::mock_0: https://bencher.dev/console/projects/save-walter-white-12345/alerts/b2329d5a-4471-48ab-bfbd-959d46ba1aa6
- bencher::mock_1: https://bencher.dev/console/projects/save-walter-white-12345/alerts/181b1cf5-d984-402a-b0f1-68f6f119fa66
- bencher::mock_2: https://bencher.dev/console/projects/save-walter-white-12345/alerts/b9b6c904-c657-4908-97db-dbeca40f8782
- bencher::mock_3: https://bencher.dev/console/projects/save-walter-white-12345/alerts/5567ff32-2829-4b6a-969a-af33ce3828db
- bencher::mock_4: https://bencher.dev/console/projects/save-walter-white-12345/alerts/49f2768f-ccda-4933-8e1d-08948f57a74d

Agora você pode ver os alertas para cada benchmark no navegador. Clique ou copie e cole os links de View alerts.


🐰 Dica: Confira a documentação sobre Limiares & Alertas para uma visão completa de como regressões de desempenho são detectadas!



🐰 Parabéns! Você capturou sua primeira regressão de desempenho! 🎉


Continue: Visão Geral do Benchmarking ➡

🤖 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.