
# Tests de performance

Le dépôt contient un outil de test de performance sous `bin/` et `benchmarks/`. Il mesure chaque mode de recherche sur des corpus réels (WordPress, Laravel) et des jeux de données synthétiques générés, produit des rapports structurés et permet de comparer deux séries de rapports.

L’outil fait partie du dépôt, pas du paquet Composer : comme 0.2.3, `benchmarks/` et les scripts `bin/bench*` sont exclus du paquet, exécutez-les depuis un clone (`git clone https://github.com/inline0/greph && cd greph && composer install`).

Les résultats publiés dans [README](https://github.com/inline0/greph#performance) proviennent d’exécutions GitHub Actions, jamais de machines locales. Les exécutions locales sont utiles pour les itérations ; celles de l’intégration continue font foi.

## Corpus

Les corpus synthétiques (`synthetic-1k`, `synthetic-10k`, `synthetic-100k-single`) sont générés sous `benchmarks/corpora/synthetic/` lors de la première exécution. Les corpus réels ne sont pas inclus : placez un clone dans `benchmarks/corpora/wordpress` ou `benchmarks/corpora/laravel` (le workflow d’intégration continue clone `WordPress/WordPress` avec `--depth=1`). Tout corpus dont le répertoire est absent est ignoré.

## Exécuter les tests de performance

```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` compare deux fichiers de séries (produits par `bench-series` ou `bench-aggregate`) et affiche un résumé Markdown, utile pour les itérations sur un chemin critique. `bin/bench-ci` lance le workflow Benchmark sur GitHub Actions via `gh` CLI.

## Catégories

Le README publie huit groupes de résultats, chacun mesurant une couche précise du moteur. Chaque groupe rassemble une ou plusieurs catégories de l’outil définies dans `benchmarks/suites/`.

### Mode d’analyse : texte

Recherche textuelle native avec des motifs littéraux, des expressions régulières et des motifs combinés. La référence publiée utilise le corpus WordPress et comprend :

- `function` littéral
- Littéral sans distinction majuscules/minuscules
- Mot littéral entier
- Nouvelle instance d’expression régulière
- Appel avec tableau d’expressions régulières
- Préfixe littéral d’expression régulière
- Suffixe littéral d’expression régulière
- Littéral exact d’une ligne avec expression régulière
- Simplification du littéral d’expression régulière

### Mode d’analyse : parcours

Parcours des fichiers uniquement, sans recherche. Mesure à lui seul le coût du parcours qui tient compte de gitignore.

### Mode d’analyse : texte parallèle

Recherche à chaîne fixe de `function` avec `1`, `2` et `4` tâches. Pour ce motif, le pool de processus ne démarre qu’au-delà de `jobs * 4_000` fichiers (voir [Processus parallèles](https://greph.inline0.dev/fr/docs/advanced/parallel)), un seuil supérieur au nombre de fichiers du corpus WordPress. Les trois lignes publiées s’exécutent donc dans un seul processus et ne montrent pas la montée en charge du pool ([#8](https://github.com/inline0/greph/issues/8)).

### Mode d’analyse : AST

Recherche AST native avec des motifs représentatifs :

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

### Mode texte indexé

Recherche textuelle indexée avec index préchauffé, utilisant les mêmes motifs que le mode d’analyse. Comprend les requêtes littérales, sans distinction de casse, sur des mots entiers, des jetons courts et des expressions régulières.

### Requêtes récapitulatives indexées

Recherche textuelle indexée avec index préchauffé, utilisant les sorties de comptage, de fichiers contenant des correspondances et de fichiers sans correspondance. Ces requêtes tirent le plus parti du stockage des occurrences, car le traitement par fichier est le moins coûteux.

### AST indexé / mis en cache

Recherche de faits AST avec index préchauffé et recherche AST mise en cache, utilisant les mêmes motifs que le mode d’analyse AST.

### Coûts de compilation

Coûts de compilation à froid pour l’index trigramme, l’index des faits AST et le cache AST. Utile pour choisir le mode à maintenir selon la charge de travail.

## Lire les résultats publiés

Le README publie un instantané de la dernière exécution d’intégration continue pour chaque référence. Chaque section provient d’une exécution GitHub Actions précise et indique le corpus, l’exécuteur, la version PHP, ainsi que le nombre d’exécutions mesurées et de préchauffages. Pour reproduire un résultat, utilisez localement la même configuration.

Les colonnes de comparaison (`rg`, `grep`, `sg`) sont recueillies dans la même tâche, sur le même exécuteur et avec le même corpus. Elles ne sont pas extrapolées à partir de tests de performance externes.

## Ajouter un test de performance

1. Ajoutez une définition de test sous `benchmarks/`.
2. Ajoutez un scénario correspondant à la suite de tests de régression s’il n’en existe pas déjà un équivalent (le comportement mesuré sera ainsi également vérifié).
3. Exécutez `./bin/bench --category <yours>` pour valider le nouveau test.
4. Comparez avec `main` à l’aide du workflow Benchmark, qui s’exécute sur les demandes de tirage touchant `src/`, `benchmarks/` ou `bin/` et publie une comparaison entre la branche de tête et la branche de base dans le résumé de l’exécution.
5. Mettez à jour le tableau README une fois que l’exécution d’intégration continue comprenant le nouveau test a été intégrée à `main`.

## Philosophie des performances

Greph ne cherche pas à dépasser ripgrep ou grep lors des analyses à froid. Ripgrep est implémenté en Rust avec une analyse littérale SIMD optimisée à la main, et les résultats publiés montrent que `rg` et GNU `grep` sont plus rapides que Greph pour chaque analyse textuelle à froid. Les objectifs sont différents :

- Être assez rapide pour que l’utilisation interactive et les boucles d’agents semblent natives.
- Répondre aux requêtes répétées à partir d’index préchauffés : les requêtes indexées d’expressions régulières, de comptage et de listes de fichiers sont plus rapides que `rg` et `grep` lors de l’analyse du même arbre.
- Dépasser `ast-grep` pour les charges de travail AST indexées et mises en cache, où les caches préchauffés de Greph évitent de réanalyser l’arbre. Les résultats de la recherche AST à froid varient : `new $CLASS()` est plus rapide que `sg`, `array($$$ITEMS)` est plus lent.
- Rendre chaque amélioration des performances mesurable et reproductible.

Les affirmations sur les performances qui ne sont pas étayées par un rapport de test ne sont pas intégrées.
