
# Pruebas de rendimiento

El repositorio incluye una infraestructura de pruebas de rendimiento en `bin/` y `benchmarks/`. Mide cada modo de búsqueda con corpus reales (WordPress, Laravel) y conjuntos de datos sintéticos generados, captura informes estructurados y permite comparar dos series de informes.

La infraestructura forma parte del repositorio, no del paquete Composer: como 0.2.3, `benchmarks/` y los scripts `bin/bench*` no se incluyen en el paquete, ejecútelos desde un clon (`git clone https://github.com/inline0/greph && cd greph && composer install`).

Las cifras publicadas en [README](https://github.com/inline0/greph#performance) proceden de ejecuciones de GitHub Actions, nunca de equipos locales. Las ejecuciones locales son útiles para iterar; las de CI son la fuente de referencia.

## Corpus

Los corpus sintéticos (`synthetic-1k`, `synthetic-10k`, `synthetic-100k-single`) se generan en `benchmarks/corpora/synthetic/` durante la primera ejecución. Los corpus reales no se incluyen: clone uno en `benchmarks/corpora/wordpress` o `benchmarks/corpora/laravel` (el flujo de trabajo de CI clona `WordPress/WordPress` con `--depth=1`). Se omite cualquier corpus cuyo directorio no exista.

## Ejecutar pruebas de rendimiento

```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` compara dos archivos de series (la salida de `bench-series` o `bench-aggregate`) e imprime un resumen Markdown, útil al iterar en una ruta crítica. `bin/bench-ci` activa el flujo de trabajo Benchmark en GitHub Actions mediante el `gh` CLI.

## Categorías

README publica ocho grupos de resultados, cada uno mide una capa concreta del motor. Cada grupo reúne una o varias categorías de la infraestructura definidas en `benchmarks/suites/`.

### Modo de análisis: texto

Búsqueda de texto nativa con patrones literales, expresiones regulares y combinados. La referencia publicada se ejecuta sobre el corpus WordPress e incluye:

- `function` literal
- Literal sin distinguir mayúsculas y minúsculas
- Literal de palabra completa
- Nueva instancia de expresión regular
- Llamada de matriz de expresiones regulares
- Literal de prefijo con expresión regular
- Literal de sufijo con expresión regular
- Literal de línea exacta con expresión regular
- Simplificación de literal con expresión regular

### Modo de análisis: recorrido

Solo recorrido de archivos, sin búsqueda. Mide por sí solo el coste del recorrido que tiene en cuenta gitignore.

### Modo de análisis: texto paralelo

Búsqueda de cadena fija para `function` con `1`, `2` y `4` tareas. Para ese patrón, el grupo de procesos de trabajo solo se inicia con más de `jobs * 4_000` archivos (consulte [Procesos de trabajo paralelos](https://greph.inline0.dev/es/docs/advanced/parallel)); el corpus WordPress tiene menos, así que las tres filas publicadas se ejecutan en un solo proceso y no muestran el escalado del grupo ([#8](https://github.com/inline0/greph/issues/8)).

### Modo de análisis: AST

Búsqueda de AST nativa con patrones representativos:

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

### Modo de texto indexado

Búsqueda de texto indexada con índices precargados y los mismos patrones que el modo de análisis. Incluye consultas literales, sin distinguir mayúsculas y minúsculas, de palabra completa, de tokens cortos y con expresiones regulares.

### Consultas de resumen indexadas

Búsqueda de texto indexada con índices precargados y resultados de recuento, archivos con coincidencias y archivos sin coincidencias. Estas consultas aprovechan más el almacén de publicaciones porque el trabajo por archivo es mínimo.

### AST indexado / en caché

Búsqueda de datos de AST indexados y búsqueda de AST en caché con los mismos patrones que el modo de análisis de AST.

### Costes de compilación

Costes de compilación en frío del índice de trigramas, el índice de datos de AST y la caché de AST. Útil para decidir qué modo mantener para una carga de trabajo determinada.

## Interpretar las cifras publicadas

README publica una instantánea de la última ejecución de CI para cada referencia. Cada sección procede de una ejecución específica de GitHub Actions e indica el corpus, el ejecutor, la versión de PHP y el número de ejecuciones y calentamientos medidos. Para reproducir una cifra, use la misma combinación en local.

Las columnas de comparación (`rg`, `grep`, `sg`) se recopilan en el mismo trabajo, en el mismo ejecutor y con el mismo corpus. No se extrapolan de pruebas externas.

## Añadir una prueba de rendimiento

1. Añada una definición de prueba de rendimiento en `benchmarks/`.
2. Añada un escenario correspondiente al conjunto de pruebas de regresión si aún no existe uno equivalente (para verificar también el comportamiento medido).
3. Ejecute `./bin/bench --category <yours>` para validar la nueva prueba.
4. Compare con `main` mediante el flujo de trabajo Benchmark, que se ejecuta en las solicitudes de incorporación de cambios que afectan a `src/`, `benchmarks/` o `bin/` y publica una comparación entre la revisión actual y la base en el resumen de la ejecución.
5. Actualice la tabla de README cuando la ejecución de CI que incluye la nueva prueba se haya integrado en `main`.

## Enfoque sobre el rendimiento

Greph no pretende superar a ripgrep ni a grep en análisis en frío. Ripgrep está implementado en Rust con análisis literal SIMD optimizado manualmente y, en las cifras publicadas, tanto `rg` como GNU `grep` son más rápidos que Greph en cada análisis de texto en frío. Los objetivos son distintos:

- Ser lo bastante rápido para que el uso interactivo y los ciclos de agentes se sientan nativos.
- Responder a consultas repetidas desde índices precargados: las consultas indexadas de expresiones regulares, recuentos y listas de archivos son más rápidas que el análisis del mismo árbol tanto con `rg` como con `grep`.
- Superar a `ast-grep` en cargas de trabajo de AST indexado y en caché, donde las cachés precargadas de Greph evitan volver a analizar el árbol. La búsqueda de AST en frío da resultados mixtos: `new $CLASS()` es más rápido que `sg`, mientras que `array($$$ITEMS)` es más lento.
- Hacer que cada mejora de rendimiento sea medible y reproducible.

Las afirmaciones sobre rendimiento sin el respaldo de un informe de pruebas no se incorporan al proyecto.
