0Pricing
PHP Academy · Lección

OPcache y compilación JIT

Acelere PHP con caché de bytecode y JIT

OPcache y compilación JIT es una lección gratuita de PHP Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de PHP Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de PHP Academy incluye 4 lecciones en total.

Almacenamiento en caché de la compilación

OPcache almacena los opcodes compilados en la memoria compartida para que PHP omita el análisis léxico, el análisis sintáctico y la compilación en cada solicitud. Además, JIT (desde PHP 8.0) compila los opcodes de ejecución frecuente en código máquina nativo. Juntos constituyen la base del rendimiento de PHP.

En esta lección se explica cómo configurar OPcache, cómo precargar código y cómo ajustar JIT.

Qué hace OPcache

El op_array compilado de cada archivo se almacena en un segmento de memoria compartida utilizado por todos los procesos de FPM. Una solicitud que encuentra el elemento en caché reutiliza directamente los opcodes. OPcache también ejecuta un optimizador (evaluación anticipada de constantes, eliminación de código inalcanzable y fusión de opcodes) la primera vez que compila un archivo.

; Core OPcache config (php.ini)
opcache.enable = 1
opcache.memory_consumption = 256      ; MB of shared memory
opcache.interned_strings_buffer = 16  ; MB for interned strings
opcache.max_accelerated_files = 20000 ; cap on cached scripts

Validación de marcas de tiempo

validate_timestamps determina si OPcache vuelve a comprobar las marcas de tiempo de modificación de los archivos. En desarrollo, manténgalo activado con un revalidate_freq corto; en producción, establézcalo en 0 para que PHP nunca consulte los archivos y realice los despliegues vaciando la caché (o reconstruyendo la imagen).

; Production: never re-stat files
opcache.validate_timestamps = 0

; Development: check every 2 seconds
; opcache.validate_timestamps = 1
; opcache.revalidate_freq = 2

Inspección de la caché

opcache_get_status() informa de la tasa de aciertos, el uso de memoria y los scripts almacenados en caché; opcache_get_configuration() muestra la configuración. Una proporción baja de aciertos o los reinicios frecuentes indican que hay muy poca memoria o demasiados archivos.

<?php
if (function_exists('opcache_get_status')) {
    $s = opcache_get_status(false);
    if ($s) {
        printf("hits:   %d\n", $s['opcache_statistics']['hits']);
        printf("misses: %d\n", $s['opcache_statistics']['misses']);
        printf("hit %%: %.2f\n", $s['opcache_statistics']['opcache_hit_rate']);
        printf("used:   %.1f MB\n", $s['memory_usage']['used_memory'] / 1048576);
    } else {
        echo "OPcache enabled but no status (likely CLI)\n";
    }
} else {
    echo "OPcache not available\n";
}
?>

Precarga

La precarga (PHP 7.4 o posterior) compila un conjunto de clases y funciones una sola vez al iniciar el servidor y las mantiene permanentemente en memoria, disponibles para todas las solicitudes sin carga automática ni enlazado por solicitud. Indique en opcache.preload un script que use require para cargar los archivos y preparar la caché.

; php.ini
opcache.preload = /app/preload.php
opcache.preload_user = www-data

Escritura de un script de precarga

El script de precarga se ejecuta en el proceso maestro. Utilice opcache_compile_file() para cargar clases sin ejecutarlas o, simplemente, use require. Los frameworks generan una lista de precarga; este es el aspecto que tiene una de ellas.

<?php
// preload.php — runs once at startup
$dir = '/app/src';
$rii = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($dir)
);

foreach ($rii as $file) {
    if ($file->getExtension() === 'php') {
        // Compiles + links the class into shared memory
        opcache_compile_file($file->getPathname());
    }
}
?>

Llegó el momento de JIT

Incluso con los opcodes almacenados en caché, la VM sigue interpretándolos. JIT compila las secuencias de opcodes de ejecución frecuente en instrucciones nativas de la CPU, eliminando el coste del despacho de la VM. La mejora es considerable en código numérico limitado por la CPU y moderada en las aplicaciones web habituales limitadas por la E/S (que pasan tiempo en la base de datos o la red, no en la CPU).

Configuración de JIT

JIT funciona dentro de OPcache, por lo que OPcache debe estar activado. opcache.jit_buffer_size asigna espacio para el código máquina generado (el valor 0 desactiva JIT). opcache.jit es un modo de cuatro dígitos que controla el desencadenador y la estrategia de optimización.

; Enable JIT (requires opcache.enable=1)
opcache.jit_buffer_size = 128M
opcache.jit = tracing        ; alias for 1254, the common default

; The 4 digits CRTO mean:
;   C - CPU optimization flags
;   R - register allocation
;   T - trigger (when to JIT)
;   O - optimization level

JIT de trazas frente a JIT de funciones

Hay dos estrategias: el JIT de funciones (modo 1205) compila funciones completas en la primera llamada; el JIT de trazas (1254, el alias predeterminado tracing) perfila la ejecución y compila los bucles y las rutas de ejecución frecuentes, lo que suele producir mejores resultados porque se especializa según los tipos observados. El JIT de trazas es la opción predeterminada recomendada.

; Tracing JIT (recommended) — compiles hot traces
opcache.jit = tracing

; Function JIT — compiles entire functions when first called
; opcache.jit = function

; Disable JIT but keep opcode cache
; opcache.jit_buffer_size = 0

Medición del impacto de JIT

JIT destaca en bucles numéricos intensivos. Este benchmark autónomo (un bucle interno similar al de Mandelbrot) representa el tipo de carga de trabajo limitada por la CPU en la que JIT puede reducir considerablemente el tiempo de ejecución; ejecútelo con y sin jit_buffer_size para comparar.

<?php
function mandelEscape(float $cr, float $ci, int $max): int {
    $zr = 0.0; $zi = 0.0; $n = 0;
    while ($n < $max && ($zr * $zr + $zi * $zi) <= 4.0) {
        $t  = $zr * $zr - $zi * $zi + $cr;
        $zi = 2.0 * $zr * $zi + $ci;
        $zr = $t;
        $n++;
    }
    return $n;
}

$start = hrtime(true);
$sum = 0;
for ($y = 0; $y < 200; $y++) {
    for ($x = 0; $x < 200; $x++) {
        $sum += mandelEscape($x / 100 - 2, $y / 100 - 1, 256);
    }
}
printf("sum=%d  time=%.2f ms\n", $sum, (hrtime(true) - $start) / 1e6);
?>

Cuándo NO esperar mejoras

En una solicitud habitual que consulta una base de datos, procesa una plantilla y devuelve JSON, la CPU realiza pocas operaciones aritméticas básicas; JIT puede producir mejoras de un solo dígito porcentual o ninguna. Priorice primero OPcache, la precarga y un buen uso de la base de datos y la caché. Reserve el ajuste de JIT para el procesamiento de imágenes, las matemáticas, los analizadores y otro código con un uso intensivo de la CPU.

Comprobación rápida

¿Qué proporciona la precarga que no proporciona el almacenamiento en caché normal de OPcache?

Resumen

OPcache almacena los op_arrays compilados en la memoria compartida y ejecuta un optimizador; establezca validate_timestamps=0 en producción y dimensione correctamente memory_consumption/max_accelerated_files. La precarga mantiene las clases elegidas residentes desde el inicio. JIT (dentro de OPcache, requiere jit_buffer_size) compila el código de ejecución frecuente en instrucciones nativas: ofrece grandes mejoras en cálculos limitados por la CPU y pocas en aplicaciones web limitadas por la E/S. Utilice opcache_get_status() para comprobarlo.

Preguntas frecuentes

¿La lección «OPcache y compilación JIT» es gratis?

Sí — el texto completo de «OPcache y compilación JIT» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de PHP Academy, actualiza a CoddyKit PRO. El curso de PHP Academy incluye 4 lecciones en total.

¿Qué aprenderé en «OPcache y compilación JIT»?

Acelere PHP con caché de bytecode y JIT Practicas PHP Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar PHP Academy?

No se requiere experiencia previa. PHP Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «OPcache y compilación JIT»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de PHP Academy?

Sí. Cada lección de PHP Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Cómo funciona Zend Engine
  2. Gestión de memoria y recolección de basura
  3. OPcache y compilación JIT
  4. Escritura de una extensión básica de PHP en C
← Volver a PHP Academy