
# Rendimiento

shikiphp realiza tokenización real de TextMate en PHP puro, así que conviene precisar dónde es rápido y dónde no.

## Qué esperar

Espere decenas o cientos de milisegundos por archivo, no microsegundos. El tokenizador almacena en caché las reglas y los analizadores compilados, las gramáticas se cargan de forma diferida (si un ejemplo nunca usa un idioma integrado, no se paga el coste de decodificarlo) y la mayoría de los patrones de las gramáticas usan `preg_*` nativo mediante una ruta rápida PCRE con equivalencia verificada; el resto lo gestiona el comparador PHP puro (consulte [Arquitectura](https://shikiphp.inline0.dev/es/docs/architecture#the-scanner-and-its-pcre-fast-path)).

Estos son tiempos de ejecuciones individuales en caliente del benchmark del repositorio
(`bench/bench.php`, tema `github-dark`), en una máquina, para archivos del corpus de
aproximadamente 55 a 105 líneas:

| Gramática | PHP 8.2 | PHP 8.4 |
| --- | --- | --- |
| JSON, YAML | 30–65 ms | 25–45 ms |
| CSS, HTML | 100–120 ms | 80–100 ms |
| Python, Rust, Go, Bash, Markdown | 190–220 ms | 125–175 ms |
| PHP | unos 290 ms | unos 170 ms |
| TypeScript, TSX | 490–510 ms | 310–370 ms |

La primera llamada para un idioma en un proceso también incluye la carga y compilación de la gramática, que solo se pagan una vez: en las mismas ejecuciones, el coste fue de 50–70 ms para JSON y de poco más de un segundo para Markdown. El coste aumenta con la complejidad de la gramática y el tamaño de la entrada, y las cifras varían según el hardware; por eso, mida en su propio entorno: clone el repositorio, ejecute `composer install` y luego `composer bench`.

## Protecciones de seguridad

El motor de expresiones regulares incluye memorización de fallos y protección contra ReDoS para que un patrón patológico ralentice el proceso en lugar de bloquearlo. También puede limitar el trabajo por línea con [`tokenizeMaxLineLength`](https://shikiphp.inline0.dev/es/docs/options#tokenizemaxlinelength), que emite un único token de texto sin formato para cualquier línea que alcance o supere una longitud determinada, como protección frente a entradas de una sola línea diseñadas para atacar.

## Caché en producción

La forma fiable de evitar que el resaltado forme parte del procesamiento de las solicitudes es **no ejecutarlo en cada solicitud**. El mismo código, con las mismas opciones, siempre produce el mismo HTML, así que se puede almacenar en caché perfectamente:

- Resalte el código durante la compilación en sitios estáticos y documentación.
- Almacene en caché el HTML generado (con una clave basada en el código y las opciones) para fragmentos proporcionados por usuarios o guardados en una base de datos, y reutilícelo hasta que cambie el código fuente.

Dentro de un proceso, reutilice un único resaltador (la fachada `Shikiphp` se encarga de ello) para compartir las cachés de gramáticas y temas entre llamadas.
