
# Výkonnostní testy

V repozitáři je měřicí nástroj v `bin/` a `benchmarks/`. Měří každý režim vyhledávání na reálných korpusech (WordPress, Laravel) i na generovaných syntetických datech, vytváří strukturované reporty a umožňuje porovnat dvě řady reportů.

Měřicí nástroj je součástí repozitáře, nikoli balíčku Composer: protože 0.2.3, `benchmarks/` a skripty `bin/bench*` nejsou součástí balíčku, spouštějte je z klonu (`git clone https://github.com/inline0/greph && cd greph && composer install`).

Publikované výsledky v [README](https://github.com/inline0/greph#performance) pocházejí z běhů GitHub Actions, nikdy z místních počítačů. Místní běhy jsou užitečné při vývoji; směrodatné jsou běhy CI.

## Korpusy

Syntetické korpusy (`synthetic-1k`, `synthetic-10k`, `synthetic-100k-single`) se při prvním spuštění generují v `benchmarks/corpora/synthetic/`. Reálné korpusy nejsou součástí balíčku: umístěte jejich klon do `benchmarks/corpora/wordpress` nebo `benchmarks/corpora/laravel` (workflow CI klonuje `WordPress/WordPress` pomocí `--depth=1`). Korpus s chybějícím adresářem se přeskočí.

## Spouštění výkonnostních testů

```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` porovná dva soubory řad (výstup `bench-series` nebo `bench-aggregate`) a vypíše souhrn Markdown, což se hodí při ladění kritické části. `bin/bench-ci` spustí workflow Benchmark na GitHub Actions prostřednictvím `gh` CLI.

## Kategorie

README publikuje osm skupin výsledků, z nichž každá měří konkrétní vrstvu enginu. Každá skupina zahrnuje jednu nebo více kategorií měřicího nástroje definovaných v `benchmarks/suites/`.

### Režim skenování: text

Nativní textové vyhledávání v doslovných, regulárních a kombinovaných vzorech. Publikované základní měření běží na korpusu WordPress a zahrnuje:

- Doslovné `function`
- Doslovné bez rozlišování velikosti písmen
- Doslovné hledání celých slov
- Nová instance regulárního výrazu
- Volání pole regulárních výrazů
- Doslovný prefix regulárního výrazu
- Doslovný suffix regulárního výrazu
- Doslovný regulární výraz pro přesný řádek
- Zjednodušení doslovného regulárního výrazu

### Režim skenování: procházení

Pouze procházení souborů, bez vyhledávání. Měří samostatné náklady na procházení respektující pravidla gitignore.

### Režim skenování: paralelní text

Vyhledávání pevného řetězce `function` s `1`, `2` a `4` úlohami. U tohoto vzoru se fond pracovních procesů spustí až při více než `jobs * 4_000` souborech (viz [Paralelní pracovní procesy](https://greph.inline0.dev/cs/docs/advanced/parallel)), což je více než počet souborů v korpusu WordPress. Všechny tři publikované řádky proto běží v jediném procesu a neukazují škálování fondu ([#8](https://github.com/inline0/greph/issues/8)).

### Režim skenování: AST

Nativní vyhledávání AST na reprezentativních vzorech:

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

### Režim indexovaného textu

Vyhledávání v zahřátém textovém indexu se stejnými vzory jako v režimu skenování. Zahrnuje doslovné dotazy, dotazy bez rozlišování velikosti písmen, celých slov, krátkých tokenů i regulárních výrazů.

### Dotazy na souhrny indexu

Vyhledávání v zahřátém textovém indexu s výstupy pro počet shod, soubory se shodami a soubory bez shod. Tyto dotazy nejvíce těží z úložiště postingů, protože zpracování jednotlivých souborů je nejlevnější.

### Indexované / cachované AST

Vyhledávání faktů AST a vyhledávání v cachovaném AST po zahřátí, se stejnými vzory jako při skenování AST.

### Náklady na sestavení

Náklady na sestavení indexu trigramů, indexu faktů AST a mezipaměti AST za studena. Užitečné při výběru režimu pro danou úlohu.

## Jak číst publikované výsledky

README publikuje přehled nejnovějšího běhu CI pro každé základní měření. Každá část vychází z konkrétního běhu GitHub Actions a uvádí korpus, běhové prostředí, verzi PHP a počet měřených běhů i zahřátí. Pokud chcete výsledek reprodukovat, použijte místně stejnou kombinaci.

Srovnávací sloupce (`rg`, `grep`, `sg`) se shromažďují v jedné úloze, na stejném běhovém prostředí a nad stejným korpusem. Nejsou extrapolovány z externích výkonnostních testů.

## Jak přidat výkonnostní test

1. Přidejte definici testu do `benchmarks/`.
2. Přidejte odpovídající scénář do regresní sady, pokud zatím neexistuje ekvivalent (ověří se tak i měřené chování).
3. Spusťte `./bin/bench --category <yours>` a ověřte nový test.
4. Porovnejte s `main` pomocí workflow Benchmark, které běží při požadavcích na začlenění změn dotýkajících se `src/`, `benchmarks/` nebo `bin/` a zveřejní porovnání větve s novou změnou a základní větve v souhrnu běhu.
5. Jakmile bude na `main` začleněn běh CI s novým testem, aktualizujte tabulku README.

## Přístup k výkonu

Greph se při skenování za studena nesnaží překonat ripgrep ani grep. Ripgrep je implementován v Rust s ručně optimalizovaným SIMD skenováním doslovných řetězců a v publikovaných výsledcích jsou `rg` i GNU `grep` rychlejší než Greph při každém studeném textovém skenování. Cíle jsou jiné:

- Dosáhnout takové rychlosti, aby interaktivní používání a smyčky agentů působily přirozeně.
- Odpovídat na opakované dotazy ze zahřátých indexů: indexované dotazy na regulární výrazy, počty a seznamy souborů jsou rychlejší než skenování stejného stromu pomocí `rg` i `grep`.
- Překonat `ast-grep` při práci s indexovaným a cachovaným AST, kde zahřáté mezipaměti Greph zabraňují opětovnému parsování stromu. Výsledky hledání ve studeném AST se liší: `new $CLASS()` je rychlejší než `sg`, zatímco `array($$$ITEMS)` je pomalejší.
- Zajistit, aby každé zlepšení výkonu bylo měřitelné a reprodukovatelné.

Výkonnostní tvrzení bez podloženého reportu z testu se nezačleňují.
