
# Suorituskykytestit

Tietovarastossa on suorituskykytestikehys hakemistossa `bin/` ja `benchmarks/`. Se mittaa kaikki hakutilat todellisilla aineistoilla (WordPress, Laravel) ja luoduilla synteettisillä aineistoilla, tallentaa rakenteiset raportit ja mahdollistaa kahden raporttisarjan vertailun.

Testikehys kuuluu tietovarastoon, ei Composer-pakettiin: 0.2.3, `benchmarks/` ja `bin/bench*`-komentosarjat on jätetty paketista pois, joten suorita ne kloonista (`git clone https://github.com/inline0/greph && cd greph && composer install`).

[README](https://github.com/inline0/greph#performance)-sivulla julkaistut luvut perustuvat GitHub Actions-ajoihin, eivät koskaan paikallisiin koneisiin. Paikalliset ajot sopivat kehityksen aikana kokeiluun; CI-ajot ovat luotettava tietolähde.

## Aineistot

Synteettiset aineistot (`synthetic-1k`, `synthetic-10k`, `synthetic-100k-single`) luodaan ensimmäisellä suorituskerralla hakemistoon `benchmarks/corpora/synthetic/`. Todelliset aineistot eivät sisälly pakettiin: aseta klooni hakemistoon `benchmarks/corpora/wordpress` tai `benchmarks/corpora/laravel` (CI-työnkulku kloonaa kohteen `WordPress/WordPress` komennolla `--depth=1`). Puuttuvan hakemiston aineisto ohitetaan.

## Suorituskykytestien ajaminen

```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` vertailee kahta sarjatiedostoa (komentojen `bench-series` tai `bench-aggregate` tulosteita) ja tulostaa yhteenvedon muodossa Markdown, mikä on hyödyllistä suorituskykykriittistä koodia kehitettäessä. `bin/bench-ci` käynnistää Benchmark-työnkulun kohteessa GitHub Actions välilehden `gh` CLI kautta.

## Luokat

README julkaisee kahdeksan tulosryhmää, joista kukin mittaa moottorin tiettyä kerrosta. Kukin ryhmä sisältää yhden tai useamman testikehyksessä `benchmarks/suites/` määritellyn luokan.

### Skannaustila: teksti

Natiivi tekstihaku kirjaimellisilla, säännöllisillä ja yhdistetyillä hakumalleilla. Julkaistussa perustasossa käytetään aineistoa WordPress, ja se sisältää:

- Kirjaimellinen `function`
- Kirjainkoosta riippumaton kirjaimellinen haku
- Kirjaimellinen kokonaisten sanojen haku
- Säännöllinen lauseke, uusi olio
- Säännöllinen lauseke, taulukkokutsu
- Säännöllinen lauseke, etuliitteen kirjaimellinen haku
- Säännöllinen lauseke, loppuosan kirjaimellinen haku
- Säännöllinen lauseke, rivin tarkka kirjaimellinen haku
- Säännöllinen lauseke, kirjaimellisen haun yhdistäminen

### Skannaustila: läpikäynti

Vain tiedostojen läpikäyntiä, ei hakua. Mittaa gitignore-tietoisen läpikävijän suorituskykyä sellaisenaan.

### Skannaustila: rinnakkainen tekstihaku

Kiinteän merkkijonon haku mallille `function` käyttäen `1`, `2` ja `4` työtä. Tällä hakumallilla työprosessi käynnistyy vasta, kun tiedostoja on yli `jobs * 4_000` (katso [Rinnakkaiset työprosessit](https://greph.inline0.dev/fi/docs/advanced/parallel)); tiedostoja on aineistossa WordPress vähemmän. Siksi kaikki kolme julkaistua riviä suoritetaan yhdessä prosessissa, eivätkä ne näytä työprosessien skaalautumista ([#8](https://github.com/inline0/greph/issues/8)).

### Skannaustila: AST

Natiivi AST-haku edustavilla hakumalleilla:

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

### Indeksoitu tekstitila

Lämmitetty indeksoitu tekstihaku samoilla hakumalleilla kuin skannaustilassa. Sisältää kirjaimelliset, kirjainkoosta riippumattomat ja kokonaisia sanoja hakevat haut, lyhyen tunnisteen haut sekä säännöllisiin lausekkeisiin perustuvat haut.

### Indeksoidut yhteenvetohaut

Lämmitetty indeksoitu tekstihaku, jonka tulosteina ovat osumien määrä, osumia sisältävät tiedostot ja tiedostot, joissa ei ole osumia. Nämä haut hyötyvät eniten osumien tallennuspaikasta, koska tiedostokohtainen työ on kevyintä.

### Indeksoitu/välimuistissa oleva AST

Lämmitetty AST-faktahaku ja välimuistissa oleva AST-haku samoilla hakumalleilla kuin AST-skannaustilassa.

### Koontikustannukset

Trigrammi-indeksin, AST-faktaindeksin ja AST-välimuistin kylmäkoonnin kustannukset. Hyödyllisiä päätettäessä, mitä tilaa kannattaa ylläpitää tiettyä työkuormaa varten.

## Julkaistujen tulosten tulkinta

README julkaisee kustakin perustasosta uusimman CI-ajon tuloskuvan. Kunkin osion tiedot ovat peräisin tietystä GitHub Actions-ajosta, ja niissä ilmoitetaan aineisto, suoritusympäristö, PHP-versio sekä mitattujen ajojen ja lämmitysajojen määrä. Jos haluat toistaa tuloksen, käytä paikallisesti samoja asetuksia.

Vertailusarakkeiden (`rg`, `grep`, `sg`) tiedot kerätään samassa työssä, samalla suoritusympäristöllä ja samasta aineistosta. Niitä ei ekstrapoloida ulkoisista suorituskykytesteistä.

## Suorituskykytestin lisääminen

1. Lisää suorituskykytestin määritelmä hakemistoon `benchmarks/`.
2. Lisää vastaava skenaario regressiotestikokoelmaan, jos vastaavaa ei vielä ole (näin myös mitattava toiminta varmistetaan).
3. Vahvista uusi suorituskykytesti komennolla `./bin/bench --category <yours>`.
4. Vertaa tuloksia kohteeseen `main` Benchmark-työnkulun avulla. Työnkulku suoritetaan vetopyynnöille, jotka koskevat tiedostoja `src/`, `benchmarks/` tai `bin/`, ja se julkaisee ajon yhteenvedossa vertailun uusimman ja lähtöversion välillä.
5. Päivitä README-taulukko, kun uuden suorituskykytestin sisältävä CI-ajo on valmistunut kohteessa `main`.

## Suorituskykyperiaatteet

Greph ei pyri ohittamaan kohteita ripgrep tai grep kylmissä skannauksissa. Ripgrep on toteutettu kielellä Rust, ja sen käsin optimoitu SIMD-kirjaimellisten merkkijonojen skannaus on julkaistujen tulosten mukaan nopeampi kuin Greph jokaisessa kylmässä tekstiskannauksessa sekä kohteessa `rg` että kohteessa GNU `grep`. Tavoitteet ovat erilaiset:

- Riittävän nopea, jotta vuorovaikutteinen käyttö ja agenttien toistuvat työvaiheet tuntuvat natiiveilta.
- Vastaa toistuviin kyselyihin lämmitetyistä indekseistä: indeksoidut säännöllisten lausekkeiden, osumamäärän ja tiedostoluetteloiden haut ovat nopeampia kuin kohteet `rg` ja `grep` samaa hakemistopuuta skannattaessa.
- Ohittaa kohteen `ast-grep` indeksoiduissa ja välimuistissa olevissa AST-työkuormissa, joissa kohteen Greph lämpimät välimuistit välttävät hakemistopuun jäsentämisen uudelleen. Kylmän AST-haun tulokset vaihtelevat: `new $CLASS()` on nopeampi kuin `sg`, `array($$$ITEMS)` hitaampi.
- Tehdä jokaisesta suorituskyvyn parannuksesta mitattava ja toistettava.

Suorituskykyväitteitä ei hyväksytä ilman testiraporttia.
