Performance baseline em CI¶
Diátaxis: explanation. Para o como rodar localmente, veja
docs/reference/cli.mdseçãobench all.
.github/workflows/ci.yml ganha um job perf-baseline que roda a
suite consolidada de benchmarks (PR #36, anotae bench all) em
matriz [ubuntu-latest, macos-latest, windows-latest] e publica o
CSV resultante como artifact com 90 dias de retenção.
Por que rodar perf em CI¶
Beta privado expõe o Anotae a hardwares heterogêneos (UBSs com PCs de várias gerações). Sem dado histórico, é difícil:
- Identificar regressões de performance entre releases.
- Decidir se um usuário com queixa de "tá lento" tem hardware que realmente justifica fallback Argon2id.
- Comparar runner de cada SO ao longo do tempo (GitHub muda hardware silenciosamente em pools sem aviso).
Executar anotae bench all em cada commit em main produz uma
trilha auditável dessas variações.
Decisões¶
Roda só em main e tag pushes¶
Um benchmark típico leva ~1–3 minutos por SO em runner padrão. Multiplicar por cada PR adicionaria ~10 minutos a cada pipeline sem ganho de informação útil (rodadas em PRs ainda em desenvolvimento têm muito ruído de revisão).
Matriz idêntica ao smoke E2E¶
[ubuntu-latest, macos-latest, windows-latest] × Python 3.12.
Mesma configuração do smoke captura tanto regressão funcional (smoke)
quanto regressão de performance (perf-baseline). Custo combinado é
manejável.
--skip-pdf por default¶
render_pdf em CI headless requer truque com QGuiApplication que
conflita com a fixture pytest-qt. O smoke E2E em subprocess
isolado já cobre o caminho do PDF.
Trade-off: perdemos métrica de export PDF nos baselines. Aceito —
quem se importa com isso pode rodar localmente com --no-skip-pdf
flag adicional (não implementado nesta PR; reabrir se necessário).
Cabeçalho informativo no CSV¶
Acrescentamos linhas iniciais # commit_sha=..., # os=...,
# ref=... antes do CSV propriamente dito. Padrão # deixa a
maioria dos parsers CSV ignorar essas linhas (ou tratar como
comentário). Útil para auditoria sem precisar baixar metadado do
artifact separadamente.
90 dias de retenção¶
GitHub Actions free tier suporta até 90 dias por default. Para analisar tendência semanal/mensal, isso cobre 12+ semanas — suficiente para detectar regressão antes do histórico expirar.
Comparação automática em PR (perf-regression-pr)¶
PR #63 adicionou um job complementar que roda em cada PR com
mudanças em anotae/, scripts/ ou pyproject.toml:
- Roda
anotae bench allproduzindoperf-current.csv. - Baixa via
gh CLIo artifactperf-baseline-ubuntu-latest-*mais recente domain(último run comsuccess). - Roda
scripts/perf-regression.pycom threshold default 20% (PR #60). - Imprime no log + emite annotations
::warning::/::error::visíveis no PR review. - Upload do
perf-current.csvcomo artifactperf-pr-<n>-<sha>(retention 30 dias — menor que baseline porque PRs vêm e vão).
Casos especiais:
- Primeira execução após PR #40 mesclar: não há baseline em main
ainda → job emite
::warning::"Sem run de baseline em main — pulando comparação" e exit 0 (não bloqueia o PR). - PR pode pular: aplicar label
skip-perfno PR para o job não rodar (útil em PRs que sabidamente regridem temporariamente — ex.: refactoring com TODO de re-otimizar). - Apenas Linux: comparação roda em
ubuntu-latest, não em matrix. macOS/Windows continuam só noperf-baselineque roda apenas em main. Manter PR rápido — comparar 3 SOs em cada PR seria 3x mais tempo de CI sem ganho proporcional.
Como consumir os artifacts¶
Análise manual¶
# Baixe o artifact 'perf-baseline-ubuntu-latest-<sha>' do release
unzip perf-baseline-ubuntu-latest-abc123.zip
cat perf-baseline.csv
Comparativo entre commits¶
Não há ferramenta automatizada nesta PR — apenas dados. Análise
visual recomendada via pandas ou planilha simples:
import pandas as pd
df = pd.read_csv("perf-baseline.csv", comment="#")
df.groupby(["benchmark"])["elapsed_seconds"].describe()
Para tendência ao longo do tempo, baixe artifacts de runs sequenciais e concatene.
Quando reabrir esta decisão¶
- Tendência analítica vira requisito → adicionar push para um serviço de armazenamento permanente (S3, branch dedicada de artifacts) com job que comenta no PR mostrando delta vs. main.
- Runner do GitHub fica caro/instável → rodar em runner self-hosted que controla a carga.
- Regressão de performance vira frequente → adicionar
pytest- benchmarkem testes individuais para enxergar regressão sem precisar esperarmainmerge.