
# Prestandatester

Repot innehåller ett benchmarkramverk i `bin/` och `benchmarks/`. Det mäter varje sökläge mot verkliga korpusar (WordPress, Laravel) och genererade syntetiska datamängder, samlar in strukturerade rapporter och låter dig jämföra två rapportserier.

Ramverket ingår i repot, inte i paketet Composer: eftersom 0.2.3, `benchmarks/` och skripten `bin/bench*` inte ingår i paketet behöver du köra dem från en klon (`git clone https://github.com/inline0/greph && cd greph && composer install`).

De publicerade resultaten i [README](https://github.com/inline0/greph#performance) kommer från GitHub Actions-körningar, aldrig från lokala datorer. Lokala körningar är användbara för iteration; CI-körningar är facit.

## Korpusar

De syntetiska korpusarna (`synthetic-1k`, `synthetic-10k`, `synthetic-100k-single`) genereras under `benchmarks/corpora/synthetic/` vid den första körningen. De verkliga korpusarna ingår inte: lägg en utcheckning i `benchmarks/corpora/wordpress` eller `benchmarks/corpora/laravel` (CI-arbetsflödet klonar `WordPress/WordPress` med `--depth=1`). Korpusar vars katalog saknas hoppas över.

## Köra prestandatester

```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` jämför två seriefiler (utdata från `bench-series` eller `bench-aggregate`) och skriver ut en Markdown-sammanfattning, användbar när du arbetar med en het kodväg. `bin/bench-ci` utlöser benchmarkarbetsflödet på GitHub Actions via `gh` CLI.

## Kategorier

README publicerar åtta resultatgrupper som var och en mäter ett specifikt lager i motorn. Varje grupp samlar en eller flera av ramverkskategorierna som definieras i `benchmarks/suites/`.

### Sökläge: text

Inbyggd textsökning med bokstavliga mönster, regex och kombinationer av dessa. Den publicerade baslinjen körs på korpusen WordPress och omfattar:

- Bokstavligt `function`
- Bokstavligt, utan hänsyn till skiftläge
- Bokstavlig helordsökning
- Ny regex-instans
- Regex-anrop med array
- Bokstavligt regex-prefix
- Bokstavligt regex-suffix
- Bokstavlig regex på exakt rad
- Kollaps av bokstavliga regex-uttryck

### Sökläge: traversal

Enbart filgenomsökning, ingen sökning. Mäter kostnaden för gitignore-medveten filgenomsökning i sig.

### Sökläge: parallell text

En sökning med fast sträng efter `function` med `1`, `2` och `4` jobb. För det mönstret startar arbetarpoolen först vid fler än `jobs * 4_000` filer (se [Parallella arbetare](https://greph.inline0.dev/sv/docs/advanced/parallel)), vilket är fler än korpusen WordPress innehåller. Därför körs alla tre publicerade rader i en enda process och visar inte poolens skalning ([#8](https://github.com/inline0/greph/issues/8)).

### Sökläge: AST

Inbyggd AST-sökning med representativa mönster:

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

### Indexerat textläge

Uppvärmd indexerad textsökning med samma mönster som i sökläget. Innehåller sökningar efter bokstavliga mönster, utan hänsyn till skiftläge, hela ord, korta token och regex.

### Indexerade sammanfattningsfrågor

Uppvärmd indexerad textsökning med utdata för antal träffar, filer med träffar och filer utan träffar. Dessa drar störst nytta av indexlagret eftersom arbetet per fil är minst kostsamt.

### Indexerad/cachad AST

Uppvärmd AST-faktasökning och cachad AST-sökning med samma mönster som i AST-sökläget.

### Byggkostnader

Kostnader för kallbygge av trigramindexet, AST-faktaindexet och AST-cachen. Användbart när du ska välja vilket läge du ska underhålla för en viss arbetsbelastning.

## Tolka publicerade resultat

README publicerar en ögonblicksbild av den senaste CI-körningen för varje baslinje. Varje avsnitt kommer från en specifik GitHub Actions-körning och är märkt med korpus, körmiljö, PHP-version samt antal mätningar och uppvärmningar. Om du behöver återskapa ett resultat använder du samma kombination lokalt.

Jämförelsekolumnerna (`rg`, `grep`, `sg`) samlas in i samma jobb, på samma körmiljö och mot samma korpus. De är inte extrapolerade från externa prestandatester.

## Lägga till ett prestandatest

1. Lägg till en benchmarkdefinition under `benchmarks/`.
2. Lägg till ett motsvarande scenario i regressionstestsviten om det inte redan finns ett likvärdigt (så att beteendet som mäts också verifieras).
3. Kör `./bin/bench --category <yours>` för att validera det nya prestandatestet.
4. Jämför med `main` via benchmarkarbetsflödet, som körs för pull-förfrågningar som berör `src/`, `benchmarks/` eller `bin/` och publicerar en jämförelse mellan aktuell version och basversion i körningssammanfattningen.
5. Uppdatera tabellen README när CI-körningen som innehåller det nya prestandatestet har landat i `main`.

## Prestandafilosofi

Greph försöker inte slå ripgrep eller grep vid kalla genomsökningar. Ripgrep är implementerat i Rust med handoptimerad SIMD-sökning efter bokstavliga strängar, och i de publicerade resultaten är både `rg` och GNU `grep` snabbare än Greph vid varje kall textsökning. Målen är annorlunda:

- Vara tillräckligt snabb för att interaktiv användning och agentloopar ska kännas inbyggda.
- Besvara upprepade frågor med uppvärmda index: indexerad regex samt indexerade frågor om antal och fillistor är snabbare än både `rg` och `grep` när de söker igenom samma träd.
- Slå `ast-grep` vid indexerade och cachade AST-arbetsbelastningar, där Grephs uppvärmda cache undviker att parsa om trädet. Kall AST-sökning ger blandade resultat: `new $CLASS()` är snabbare än `sg`, `array($$$ITEMS)` är långsammare.
- Göra varje prestandaförbättring mätbar och reproducerbar.

Prestandapåståenden utan stöd i en benchmarkrapport godkänns inte.
