必须运行100次以上才能准确测单次执行耗时,因jit需第2–5次编译、第10次后才稳定,仅测一次microtime(true)差值结果不可信。

用 microtime(true) 测单次执行耗时,但必须跑够 100 次以上
JIT 的优化依赖热点识别,首次执行不生效,第 2–5 次开始编译,稳定性能要从第 10 次之后看。只测一次 microtime(true) 差值,结果完全不可信。
常见错误是写个 for ($i = 0; $i 就去比对时间——这连 JIT 触发条件都没满足。
- 用循环至少跑
100次,取后80次的平均值(剔除前 20 次冷启动抖动) - 每次循环内调用目标函数,不要把循环逻辑塞进被测函数里(否则测的是 PHP 循环开销,不是 JIT 效果)
- 确保脚本全程不触发 GC 或内存重分配(比如避免在循环里反复
json_encode大数组)
对比必须在同一 PHP 进程生命周期内完成
PHP-FPM worker 或 CLI 脚本重启会清空 JIT 缓存,跨进程测 php -v 前后时间,等于拿冷启动比热执行,结果虚高 3–5 倍。
真实场景中,Web 请求是复用 worker 的,所以测试也得模拟这个行为:要么用 php-fpm + ab / wrk 压测,要么 CLI 下用 pcntl_fork 模拟多请求,但更简单的是直接跑长生命周期 CLI 脚本。
- CLI 测试时加
-d opcache.enable_cli=1,否则opcache.jit不生效 - 别用
include动态加载被测文件——每次 include 都算新脚本,JIT 重新分析 - 用
opcache_get_status()['jit']['buffer_free']确认缓冲区没满(buffer_free接近 0 表示 JIT 编译失败或缓冲不足)
opcache.jit=1205 和 1235 对 CPU 密集型任务的实际差异
这两个值决定 JIT 怎么选代码编译:1205 是“函数级+循环追踪”,适合递归、数学计算类;1235 加了“类型推测+函数内联”,对含大量小函数调用的逻辑更友好,但编译开销略高。
你测出来的提升幅度,可能差 15% 以上——不是 JIT 本身不行,而是策略和代码不匹配。
- 纯数值循环(如累加、素数筛)用
1205更稳,实测快 2.4×(vs PHP 7.4) - 模板渲染、ORM 构建这类函数调用密集型,换
1235后 JIT 编译命中率能从 60% 提到 89%,响应时间再降 12% - 如果
opcache.jit_buffer_size小于64M,哪怕设了1235,JIT 也会静默退化为1205甚至关闭
别信 phpbench 默认配置,它默认禁用 OPcache
很多团队用 phpbench 跑基准,但它的 CLI 模式默认不加载 opcache,opcache.jit 彻底无效,测出来全是解释器速度。
必须显式传参激活:
php -d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.jit=1205 -d opcache.jit_buffer_size=128M vendor/bin/phpbench run --report=aggregate
漏掉任意一个 -d,结果就和生产环境对不上。尤其 opcache.enable_cli=1,宝塔或 Docker 环境里经常被忽略。
JIT 缓冲区是否真正分配、函数是否被实际编译、编译后有没有被复用——这些细节藏在 opcache_get_status() 返回的 jit 字段里,不查就等于蒙眼调优。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











