Benchmarks
O repositório inclui uma ferramenta de benchmarks em bin/ e benchmarks/. Ela mede cada modo de pesquisa com conjuntos de dados reais (WordPress, Laravel) e conjuntos sintéticos gerados, captura relatórios estruturados e permite comparar duas séries de relatórios.
A ferramenta faz parte do repositório, não do pacote Composer: como 0.2.3, benchmarks/ e os scripts bin/bench* não são incluídos no pacote, execute-os a partir de um clone (git clone https://github.com/inline0/greph && cd greph && composer install).
Os números publicados em README vêm de execuções do GitHub Actions, nunca de máquinas locais. As execuções locais são úteis para iterar; as execuções do CI são a fonte confiável.
Conjuntos de dados
Os conjuntos sintéticos (synthetic-1k, synthetic-10k, synthetic-100k-single) são gerados em benchmarks/corpora/synthetic/ na primeira execução. Os conjuntos reais não estão incluídos: coloque um checkout em benchmarks/corpora/wordpress ou benchmarks/corpora/laravel (o fluxo de trabalho do CI clona WordPress/WordPress com --depth=1). Um conjunto cujo diretório não exista será ignorado.
Executar benchmarks
# Full benchmark suite, every corpus that is present
./bin/bench
# Specific category (the category names used in benchmarks/suites/)
./bin/bench --category text
./bin/bench --category ast
# Compare against external tools when available
./bin/bench --compare rg,grep
./bin/bench --compare sg
# Choose a corpus
./bin/bench --corpus wordpress
./bin/bench --corpus laravel
./bin/bench --corpus synthetic-1k
# Write the run as JSON
./bin/bench --corpus wordpress --output build/run-1.json
# Measured series: 5 runs after 1 warmup run
./bin/bench-series --repeat 5 --warmup 1 --corpus wordpress --output build/head-series.json
# Aggregate separate runs into one series
./bin/bench-aggregate --output build/head-series.json build/run-*.json
bin/bench-compare base-series.json head-series.json compara dois arquivos de séries (a saída de bench-series ou bench-aggregate) e exibe um resumo Markdown, útil ao iterar em um caminho crítico. bin/bench-ci aciona o fluxo de trabalho Benchmark em GitHub Actions pelo gh CLI.
Categorias
README publica oito grupos de resultados, cada um medindo uma camada específica do mecanismo. Cada grupo reúne uma ou mais categorias da ferramenta definidas em benchmarks/suites/.
Modo de varredura: texto
Pesquisa nativa de texto com padrões literais, regex e combinados. A linha de base publicada usa o conjunto WordPress e inclui:
functionliteral- Literal sem distinção entre maiúsculas e minúsculas
- Palavra inteira literal
- Nova instância de regex
- Chamada de matriz de regex
- Literal como prefixo de regex
- Literal como sufixo de regex
- Literal de linha exata de regex
- Colapso de literal de regex
Modo de varredura: travessia
Percorrimento de arquivos sem pesquisa. Mede somente o custo do percorrimento que respeita gitignore.
Modo de varredura: texto paralelo
Pesquisa de cadeia fixa por function com 1, 2 e 4 tarefas. Para esse padrão, o conjunto de workers só é iniciado acima de jobs * 4_000 arquivos (consulte Workers paralelos); o conjunto WordPress contém menos arquivos. Por isso, todas as três linhas publicadas são executadas em um único processo e não mostram o escalonamento do conjunto (#8).
Modo de varredura: AST
Pesquisa nativa de AST com padrões representativos:
new $CLASS()array($$$ITEMS)
Modo de texto indexado
Pesquisa de texto indexado aquecido com os mesmos padrões do modo de varredura. Inclui consultas literais, sem distinção entre maiúsculas e minúsculas, de palavra inteira, de tokens curtos e regex.
Consultas de resumo indexadas
Pesquisa de texto indexado aquecido com saídas de contagem, arquivos com correspondências e arquivos sem correspondências. Essas consultas se beneficiam mais do armazenamento de ocorrências porque o trabalho por arquivo é o mais barato.
AST indexada/em cache
Pesquisa aquecida de fatos de AST e pesquisa de AST em cache com os mesmos padrões do modo de varredura de AST.
Custos de compilação
Custos de compilação a frio para o índice de trigramas, o índice de fatos de AST e o cache de AST. Útil para decidir qual modo manter para uma determinada carga de trabalho.
Como interpretar os números publicados
README publica uma captura da execução mais recente do CI para cada linha de base. Cada seção vem de uma execução específica do GitHub Actions e está identificada com o conjunto de dados, o executor, a versão PHP e o número de execuções medidas e aquecimentos. Para reproduzir um número, use a mesma combinação localmente.
As colunas de comparação (rg, grep, sg) são coletadas na mesma tarefa, no mesmo executor e com o mesmo conjunto de dados. Elas não são extrapoladas de benchmarks externos.
Como adicionar um benchmark
- Adicione uma definição de benchmark em
benchmarks/. - Adicione um cenário correspondente à suíte de regressão se ainda não houver um equivalente (assim, o comportamento medido também é verificado).
- Execute
./bin/bench --category <yours>para validar o novo benchmark. - Compare com
mainusando o fluxo de trabalho Benchmark, executado em solicitações de pull que alteramsrc/,benchmarks/oubin/e publica uma comparação entre a revisão atual e a base no resumo da execução. - Atualize a tabela README quando a execução do CI que inclui o novo benchmark chegar a
main.
Filosofia de desempenho
Greph não tenta superar ripgrep ou grep em varreduras a frio. Ripgrep é implementado em Rust com varredura literal SIMD ajustada manualmente e, nos números publicados, tanto rg quanto GNU grep são mais rápidos que Greph em todas as varreduras de texto a frio. Os objetivos são diferentes:
- Ser rápido o bastante para que o uso interativo e os ciclos dos agentes pareçam nativos.
- Responder a consultas repetidas usando índices aquecidos: consultas de regex indexadas, de contagem indexadas e de lista de arquivos são mais rápidas do que a varredura de mesma árvore por
rgegrep. - Superar
ast-grepem cargas de trabalho de AST indexada e em cache, nas quais os caches aquecidos de Greph evitam analisar novamente a árvore. A pesquisa de AST a frio tem resultados mistos:new $CLASS()é mais rápido quesg,array($$$ITEMS)é mais lento. - Tornar cada melhoria de desempenho mensurável e reproduzível.
Alegações de desempenho sem respaldo em um relatório de benchmark não são aceitas.