The JIT (PHP 8.0, rebuilt on the IR framework in 8.4) compiles hot opcodes to machine code. tracing mode, the one the manual recommends, compiles hot paths through loops and functions; function mode compiles whole functions. Since 8.4, opcache.jit defaults to disable and opcache.jit_buffer_size to 64M (before: tracing and 0, which also meant off), so one line turns it on. A CPU-bound loop:
<?php
function mandel(int $size): int // points of a grid inside the Mandelbrot set
{
for ($inside = 0, $y = 0; $y < $size; $y++) {
for ($x = 0; $x < $size; $x++) {
[$cr, $ci, $zr, $zi] = [3.0 * $x / $size - 2.0, 2.0 * $y / $size - 1.0, 0.0, 0.0];
for ($i = 0; $i < 100 && $zr * $zr + $zi * $zi < 4.0; $i++) {
[$zr, $zi] = [$zr * $zr - $zi * $zi + $cr, 2.0 * $zr * $zi + $ci];
}
$inside += (int) ($i === 100);
}
}
return $inside;
}
$start = hrtime(true);
$n = mandel(1200);
printf("%-8s %d points %.3f s\n", ini_get('opcache.jit'), $n, (hrtime(true) - $start) / 1e9);$ for m in disable function tracing; do > php -d opcache.enable_cli=1 -d opcache.jit=$m mandel.php; done disable 371477 points 3.432 s function 371477 points 1.832 s tracing 371477 points 1.340 s
On this WSL2 6 machine tracing ran the loop 1.9 to 2.6 times faster across four runs. On the Laravel 2,157 page, two sessions each, it gave 1,463 and 1,508 requests per second against 1,404 and 1,431 without: 4 to 5%, which is typical: web requests spend their time in hash lookups, string building and waiting on MySQL 524 , which are already C code or I/O. Use the JIT for image work, parsers or math, and measure your own pages before keeping it anywhere else.