
# Výkonnostné testy

V repozitári sa nachádza sada nástrojov na výkonnostné testy v `bin/` a `benchmarks/`. Meria každý režim vyhľadávania na reálnych korpusoch (WordPress, Laravel) a syntetických dátových súboroch vytvorených automaticky, zaznamenáva štruktúrované reporty a umožňuje porovnať dve série reportov.

Testovacia sada je súčasťou repozitára, nie balíka Composer: keďže 0.2.3, `benchmarks/` a skripty `bin/bench*` nie sú zahrnuté v balíku, spúšťajte ich z klonu (`git clone https://github.com/inline0/greph && cd greph && composer install`).

Publikované čísla v [README](https://github.com/inline0/greph#performance) pochádzajú zo spustení GitHub Actions, nikdy z lokálnych počítačov. Lokálne spustenia sú užitočné pri vývoji; rozhodujúce sú spustenia CI.

## Korpusy

Syntetické korpusy (`synthetic-1k`, `synthetic-10k`, `synthetic-100k-single`) sa pri prvom spustení generujú v `benchmarks/corpora/synthetic/`. Reálne korpusy nie sú zahrnuté: umiestnite ich klon do `benchmarks/corpora/wordpress` alebo `benchmarks/corpora/laravel` (pracovný postup CI klonuje `WordPress/WordPress` pomocou `--depth=1`). Korpus s chýbajúcim adresárom sa preskočí.

## Spúšťanie výkonnostných testov

```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 súbory sérií (výstup z `bench-series` alebo `bench-aggregate`) a vypíše súhrn Markdown, čo je užitočné pri úpravách kritickej časti kódu. `bin/bench-ci` spustí pracovný postup Benchmark na GitHub Actions prostredníctvom `gh` CLI.

## Kategórie

README publikuje osem skupín výsledkov, z ktorých každá meria konkrétnu vrstvu nástroja. Každá skupina zahŕňa jednu alebo viac kategórií testovacej sady definovaných v `benchmarks/suites/`.

### Režim skenovania: text

Natívne textové vyhľadávanie v doslovných, regulárnych a kombinovaných vzoroch. Publikované základné meranie sa vykonáva na korpuse WordPress a zahŕňa:

- Doslovný `function`
- Doslovný, bez rozlišovania veľkosti písmen
- Doslovný, celé slovo
- Nová inštancia regulárneho výrazu
- Volanie poľa regulárnych výrazov
- Doslovný prefix regulárneho výrazu
- Doslovný sufix regulárneho výrazu
- Doslovný regulárny výraz pre presný riadok
- Zlučovanie doslovných regulárnych výrazov

### Režim skenovania: prechádzanie

Iba prechádzanie súborov, bez vyhľadávania. Meria sa samostatná réžia prechádzača, ktorý zohľadňuje gitignore.

### Režim skenovania: paralelný text

Vyhľadávanie pevného reťazca `function` s `1`, `2` a `4` úlohami. Pri tomto vzore sa skupina procesov spustí až nad hranicou `jobs * 4_000` súborov (pozri [Paralelné procesy](https://greph.inline0.dev/sk/docs/advanced/parallel)). Korpus WordPress obsahuje menej súborov, preto sa všetky tri publikované riadky vykonávajú v jednom procese a neukazujú škálovanie skupiny procesov ([#8](https://github.com/inline0/greph/issues/8)).

### Režim skenovania: AST

Natívne vyhľadávanie AST na reprezentatívnych vzoroch:

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

### Režim indexovaného textu

Vyhľadávanie v zahriatom textovom indexe s rovnakými vzormi ako v režime skenovania. Zahŕňa doslovné, nerozlišujúce veľkosť písmen, celoslovné, krátke tokenové a regulárne dotazy.

### Súhrnné dotazy na index

Vyhľadávanie v zahriatom textovom indexe s výstupmi: počet, súbory so zhodami a súbory bez zhôd. Najviac z nich ťaží úložisko výskytov, pretože práca na jeden súbor je najmenšia.

### Indexované / ukladané do vyrovnávacej pamäte AST

Vyhľadávanie faktov v zahriatom indexe AST a vyhľadávanie v medzipamäti AST s rovnakými vzormi ako v režime skenovania AST.

### Náklady na zostavenie

Náklady na vytvorenie trigramového indexu, indexu faktov AST a medzipamäte AST bez predchádzajúceho zostavenia. Užitočné pri rozhodovaní, ktorý režim zachovať pre dané pracovné zaťaženie.

## Ako čítať publikované čísla

README publikuje snímku najnovšieho spustenia CI pre každé základné meranie. Každá sekcia vychádza z konkrétneho spustenia GitHub Actions a uvádza korpus, spúšťač, verziu PHP a počet meraných behov a zahrievacích behov. Ak chcete číslo reprodukovať, použite lokálne rovnakú kombináciu.

Porovnávacie stĺpce (`rg`, `grep`, `sg`) sa zhromažďujú v rámci tej istej úlohy, na tom istom spúšťači a s tým istým korpusom. Nie sú extrapolované z externých výkonnostných testov.

## Ako pridať výkonnostný test

1. Pridajte definíciu testu do `benchmarks/`.
2. Ak ešte neexistuje ekvivalentný test, pridajte príslušný scenár do regresnej sady (overí sa tak aj správanie, ktoré sa meria).
3. Spustením `./bin/bench --category <yours>` overte nový test.
4. Porovnajte ho s `main` pomocou pracovného postupu Benchmark, ktorý sa spúšťa pri požiadavkách na stiahnutie zasahujúcich do `src/`, `benchmarks/` alebo `bin/` a v súhrne spustenia zverejňuje porovnanie aktuálnej verzie so základnou.
5. Keď sa spustenie CI s novým testom dostane do `main`, aktualizujte tabuľku README.

## Prístup k výkonu

Greph sa nesnaží prekonať ripgrep ani grep pri studených skenovaniach. Ripgrep je implementovaný v Rust a využíva ručne optimalizované skenovanie doslovných reťazcov pomocou SIMD. Publikované výsledky ukazujú, že `rg` aj GNU `grep` sú pri každom studenom skenovaní textu rýchlejšie než Greph. Ciele sú odlišné:

- Byť dostatočne rýchly, aby interaktívne používanie a cykly agentov pôsobili prirodzene.
- Odpovedať na opakované dotazy pomocou zahriatych indexov: indexované regulárne výrazy, počty a zoznamy súborov sú rýchlejšie než skenovanie rovnakého stromu pomocou `rg` aj `grep`.
- Prekonať `ast-grep` pri indexovaných a cachovaných úlohách AST, kde zahriate vyrovnávacie pamäte Greph predchádzajú opätovnému parsovaniu stromu. Výsledky studeného vyhľadávania AST sa líšia: `new $CLASS()` je rýchlejší než `sg`, `array($$$ITEMS)` je pomalší.
- Dosiahnuť, aby každé zlepšenie výkonu bolo merateľné a reprodukovateľné.

Tvrdenia o výkone, ktoré nie sú podložené výkazom z výkonnostného testu, sa nezaraďujú.
