Benchmark
Il repository include un harness di benchmark in bin/ e benchmarks/. Misura ogni modalità di ricerca su corpus reali (WordPress, Laravel) e set di dati sintetici generati, acquisisce report strutturati e consente di confrontare due serie di report.
L'harness fa parte del repository, non del pacchetto Composer: poiché 0.2.3, benchmarks/ e gli script bin/bench* sono esclusi dal pacchetto, eseguili da un clone (git clone https://github.com/inline0/greph && cd greph && composer install).
I risultati pubblicati in README provengono da esecuzioni GitHub Actions, mai da macchine locali. Le esecuzioni locali sono utili per le iterazioni; quelle della CI sono il riferimento.
Corpus
I corpus sintetici (synthetic-1k, synthetic-10k, synthetic-100k-single) vengono generati in benchmarks/corpora/synthetic/ alla prima esecuzione. I corpus reali non sono inclusi: inserisci un checkout in benchmarks/corpora/wordpress o benchmarks/corpora/laravel (il workflow CI clona WordPress/WordPress con --depth=1). I corpus con directory mancanti vengono ignorati.
Esecuzione dei benchmark
# 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 confronta due file di serie (l'output di bench-series o bench-aggregate) e stampa un riepilogo Markdown, utile durante le iterazioni su un percorso critico. bin/bench-ci avvia il workflow Benchmark su GitHub Actions tramite il gh CLI.
Categorie
README pubblica otto gruppi di risultati, ciascuno dedicato alla misurazione di uno specifico livello del motore. Ogni gruppo raccoglie una o più categorie dell'harness definite in benchmarks/suites/.
Modalità di scansione: testo
Ricerca nativa nel testo con pattern letterali, regex e combinati. La baseline pubblicata usa il corpus WordPress e include:
functionletterale- Letterale senza distinzione tra maiuscole e minuscole
- Letterale per parola intera
- Nuova istanza regex
- Chiamata con array di regex
- Regex con prefisso letterale
- Regex con suffisso letterale
- Regex letterale di riga esatta
- Semplificazione di regex letterali
Modalità di scansione: attraversamento
Solo attraversamento dei file, senza ricerca. Misura il costo del walker che rispetta gitignore.
Modalità di scansione: testo parallelo
Ricerca a stringa fissa di function con 1, 2 e 4 processi. Per questo pattern, il pool di worker si avvia solo oltre jobs * 4_000 file (vedi Worker paralleli), più di quanti ne abbia il corpus WordPress: tutte e tre le righe pubblicate vengono quindi eseguite in un singolo processo e non mostrano la scalabilità del pool (#8).
Modalità di scansione: AST
Ricerca nativa AST con pattern rappresentativi:
new $CLASS()array($$$ITEMS)
Modalità testo indicizzato
Ricerca nel testo indicizzato a caldo con gli stessi pattern della modalità di scansione. Include query letterali, senza distinzione tra maiuscole e minuscole, per parola intera, con token brevi e regex.
Query di riepilogo indicizzate
Ricerca nel testo indicizzato a caldo con output di conteggio, file con corrispondenze e file senza corrispondenze. Queste query traggono il massimo vantaggio dall'archivio dei postings, perché il lavoro per file è minimo.
AST indicizzato / memorizzato nella cache
Ricerca di fatti AST a caldo e ricerca AST in cache con gli stessi pattern della modalità di scansione AST.
Costi di compilazione
Costi di compilazione a freddo per l'indice trigramma, l'indice dei fatti AST e la cache AST. Utile per decidere quale modalità mantenere per un determinato carico di lavoro.
Interpretazione dei risultati pubblicati
README pubblica un'istantanea dell'ultima esecuzione CI per ogni baseline. Ogni sezione si basa su una specifica esecuzione GitHub Actions ed è etichettata con il corpus, il runner, la versione PHP e il numero di esecuzioni misurate e di warmup. Per riprodurre un risultato, usa localmente la stessa combinazione.
Le colonne di confronto (rg, grep, sg) vengono raccolte nello stesso job, sullo stesso runner e con lo stesso corpus. Non sono estrapolate da benchmark esterni.
Come aggiungere un benchmark
- Aggiungi una definizione di benchmark in
benchmarks/. - Aggiungi uno scenario corrispondente alla suite di regressione, se non ne esiste già uno equivalente (così si verifica anche il comportamento misurato).
- Esegui
./bin/bench --category <yours>per convalidare il nuovo benchmark. - Confrontalo con
maintramite il workflow Benchmark, che viene eseguito sulle pull request che modificanosrc/,benchmarks/obin/e pubblica un confronto tra head e base nel riepilogo dell'esecuzione. - Aggiorna la tabella README quando l'esecuzione CI che include il nuovo benchmark è stata integrata in
main.
Filosofia delle prestazioni
Greph non cerca di superare ripgrep o grep nelle scansioni a freddo. Ripgrep è implementato in Rust con scansione SIMD di stringhe letterali ottimizzata manualmente; nei risultati pubblicati, sia rg sia GNU grep sono più veloci di Greph in ogni scansione del testo a freddo. Gli obiettivi sono diversi:
- Essere abbastanza veloce perché l'uso interattivo e i cicli degli agenti risultino naturali.
- Rispondere alle query ripetute usando indici a caldo: le query regex indicizzate, di conteggio e di elenchi di file sono più veloci sia di
rgsia della scansione digrepsullo stesso albero. - Superare
ast-grepnei carichi di lavoro AST indicizzati e in cache, dove le cache a caldo di Greph evitano di analizzare nuovamente l'albero. La ricerca AST a freddo dà risultati misti:new $CLASS()è più veloce disg,array($$$ITEMS)è più lento. - Rendere misurabile e riproducibile ogni miglioramento delle prestazioni.
Le dichiarazioni sulle prestazioni prive di un report di benchmark non vengono integrate.