
# Benchmarks

De repository bevat een benchmarkharnas onder `bin/` en `benchmarks/`. Het meet elke zoekmodus met corpora uit de praktijk (WordPress, Laravel) en gegenereerde synthetische datasets, legt gestructureerde rapporten vast en laat u twee rapportreeksen met elkaar vergelijken.

Het harnas maakt deel uit van de repository, niet van het Composer-pakket: 0.2.3, `benchmarks/` en de `bin/bench*`-scripts zijn namelijk niet opgenomen in het pakket. Voer ze daarom uit vanuit een kloon (`git clone https://github.com/inline0/greph && cd greph && composer install`).

De gepubliceerde cijfers in de [README](https://github.com/inline0/greph#performance) zijn afkomstig uit GitHub Actions-runs, nooit van lokale machines. Lokale runs zijn nuttig om te itereren; CI-runs zijn leidend.

## Corpora

De synthetische corpora (`synthetic-1k`, `synthetic-10k`, `synthetic-100k-single`) worden bij de eerste run gegenereerd onder `benchmarks/corpora/synthetic/`. De corpora uit de praktijk zijn niet inbegrepen: plaats een checkout in `benchmarks/corpora/wordpress` of `benchmarks/corpora/laravel` (de CI-workflow kloont `WordPress/WordPress` met `--depth=1`). Een corpus waarvan de map ontbreekt, wordt overgeslagen.

## Benchmarks uitvoeren

```bash
# 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` vergelijkt twee reeksbestanden (de uitvoer van `bench-series` of `bench-aggregate`) en toont een Markdown-samenvatting, handig bij het optimaliseren van een veelgebruikte codepad. `bin/bench-ci` start de Benchmark-workflow op GitHub Actions via de `gh` CLI.

## Categorieën

De README publiceert acht resultaatgroepen, die elk een specifieke laag van de engine meten. Elke groep verzamelt een of meer harnesscategorieën die zijn gedefinieerd in `benchmarks/suites/`.

### Scanmodus: tekst

Native tekstzoekopdrachten met letterlijke, regex- en gecombineerde patronen. De gepubliceerde basisrun gebruikt het corpus WordPress en bevat:

- Letterlijk `function`
- Letterlijk, hoofdletterongevoelig
- Letterlijk, volledig woord
- Regex, nieuwe instantie
- Regex-arrayaanroep
- Regex-prefixletterlijk
- Regex-suffixletterlijk
- Regex, exacte regelliteral
- Regex, letterlijke samenvoeging

### Scanmodus: traverseren

Alleen bestanden doorlopen, niet zoeken. Meet de kosten van de gitignore-bewuste doorloper op zichzelf.

### Scanmodus: parallelle tekst

Zoeken naar een vaste tekenreeks `function` met `1`, `2` en `4` taken. Voor dit patroon start de workerpool pas boven `jobs * 4_000` bestanden (zie [Parallelle workers](https://greph.inline0.dev/nl/docs/advanced/parallel)), meer dan het corpus WordPress bevat. Alle drie gepubliceerde rijen draaien daarom in één proces en laten geen schaling van de pool zien ([#8](https://github.com/inline0/greph/issues/8)).

### Scanmodus: AST

Native AST-zoekopdrachten met representatieve patronen:

- `new $CLASS()`
- `array($$$ITEMS)`

### Geïndexeerde tekstmodus

Opgewarmd zoeken in geïndexeerde tekst met dezelfde patronen als de scanmodus. Bevat letterlijke zoekopdrachten, zoekopdrachten zonder onderscheid tussen hoofdletters en kleine letters, volledige woorden, korte tokens en regex-query's.

### Geïndexeerde samenvattingsquery's

Opgewarmd zoeken in geïndexeerde tekst met de uitvoeropties tellen, bestanden met overeenkomsten en bestanden zonder overeenkomsten. Deze zijn het meest gebaat bij de postings-opslag, omdat het werk per bestand het kleinst is.

### Geïndexeerde / gecachte AST

Opgewarmd zoeken naar AST-feiten en zoeken in de AST-cache met dezelfde patronen als de AST-scanmodus.

### Buildkosten

De kosten van een koude build voor de trigramindex, de AST-feitenindex en de AST-cache. Nuttig bij het bepalen welke modus u voor een bepaalde werklast wilt onderhouden.

## De gepubliceerde cijfers lezen

De README publiceert voor elke basisrun een momentopname van de meest recente CI-run. Elke sectie is afkomstig uit een specifieke GitHub Actions-run en vermeldt het corpus, de runner, de versie van PHP en het aantal gemeten runs en opwarmruns. Als u een cijfer wilt reproduceren, gebruikt u lokaal dezelfde combinatie.

De vergelijkingskolommen (`rg`, `grep`, `sg`) worden verzameld in dezelfde job, op dezelfde runner en met hetzelfde corpus. Ze zijn niet geëxtrapoleerd uit externe benchmarks.

## Een benchmark toevoegen

1. Voeg een benchmarkdefinitie toe onder `benchmarks/`.
2. Voeg een bijbehorend scenario toe aan de regressiesuite als er nog geen gelijkwaardig scenario is (zodat ook het gemeten gedrag wordt gecontroleerd).
3. Voer `./bin/bench --category <yours>` uit om de nieuwe benchmark te valideren.
4. Vergelijk met `main` via de Benchmark-workflow. Deze draait op pull requests die `src/`, `benchmarks/` of `bin/` wijzigen en plaatst een vergelijking tussen de head- en basistak in het runoverzicht.
5. Werk de tabel README bij zodra de CI-run met de nieuwe benchmark is samengevoegd in `main`.

## Prestatievisie

Greph probeert ripgrep of grep niet te verslaan bij koude scans. Ripgrep is geïmplementeerd in Rust met handmatig afgestemde SIMD-literal-scanning. In de gepubliceerde cijfers zijn zowel `rg` als GNU `grep` sneller dan Greph bij elke koude tekstscan. De doelen zijn anders:

- Snel genoeg zijn om interactief gebruik en agentloops natuurlijk te laten aanvoelen.
- Herhaalde query's beantwoorden vanuit opgewarmde indexen: geïndexeerde regex-, tel- en bestandslijstquery's zijn sneller dan zowel `rg` als `grep` bij het scannen van dezelfde boom.
- `ast-grep` verslaan bij geïndexeerde en gecachte AST-werklasten, waarbij de warme caches van Greph voorkomen dat de boom opnieuw wordt geparseerd. Zoeken in een koude AST levert wisselende resultaten op: `new $CLASS()` is sneller dan `sg`, `array($$$ITEMS)` is langzamer.
- Elke prestatieverbetering meetbaar en reproduceerbaar maken.

Prestatieclaims zonder benchmarkrapport worden niet opgenomen.
