PHP8 JIT实测:性能提升还是噱头?

2026-07-11 2 min read 11

问题:你的PHP8 JIT真的跑起来了吗?

去年我把公司一个老项目从PHP7.4升级到PHP8.1,顺手开了JIT,结果线上接口响应时间反而涨了5%。排查半天发现是JIT配置不当,还踩了opcache.file_cache的坑。今天不扯理论,直接上实测数据,告诉你JIT到底该不该开、怎么开。

方案对比:JIT vs 无JIT

我们对比三种场景:

  • 方案A:PHP8.2 + JIT关闭(仅OPcache)
  • 方案B:PHP8.2 + JIT开启(tracing模式,默认配置)
  • 方案C:PHP8.2 + JIT开启(function模式,buffer_size=64M)

测试环境:Ubuntu 22.04, PHP 8.2.10 (cli), Intel i7-12700, 32GB RAM, SSD。所有测试执行5次取中位数。

具体实现:配置与代码

1. 安装PHP8.2并启用JIT

# 安装PHP8.2(以Ubuntu为例)
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
sudo apt install php8.2-cli php8.2-common php8.2-opcache -y

# 查看PHP版本
php -v
# 输出:PHP 8.2.10 (cli) (built: Sep 12 2023 12:00:00) ( NTS )

# 编辑php.ini
sudo vim /etc/php/8.2/cli/php.ini

关键配置项(方案B):

[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.jit=tracing
opcache.jit_buffer_size=100M

方案C改为:

opcache.jit=function
opcache.jit_buffer_size=64M

重启PHP-FPM或CLI后生效:sudo systemctl restart php8.2-fpm(如果使用FPM)。

2. 基准测试代码

我们写两个典型场景:CPU密集型(计算斐波那契)和I/O密集型(模拟文件读取)。

运行:php benchmark.php。注意:每次测试前清空OPcache缓存:php -r 'opcache_reset();'

3. 真实Web应用压测

使用Laravel 10.28 + PHP8.2,模拟一个带数据库查询的API:

// routes/api.php
Route::get('/users', function () {
    return \App\Models\User::select('id', 'name', 'email')
        ->where('status', 1)
        ->orderBy('id')
        ->take(100)
        ->get();
});

压测命令(使用wrk2):

# 安装wrk2
sudo apt install build-essential libssl-dev git -y
git clone https://github.com/giltene/wrk2.git
cd wrk2 && make
sudo cp wrk /usr/local/bin/

# 压测:100个连接,持续30秒
wrk -t4 -c100 -d30s --latency http://localhost:8000/api/users

效果数据:数字说话

测试项方案A(无JIT)方案B(tracing)方案C(function)
fib(35) 耗时2.341s0.892s0.915s
IO任务1000次0.123s0.118s0.121s
Laravel API RPS1850 req/s1920 req/s1900 req/s
Laravel API p99延迟12ms11ms11ms

结论:

  • CPU密集型任务:JIT开启后性能提升约2.6倍(tracing模式略优于function)。
  • I/O密集型任务:几乎无差异(JIT不优化I/O等待)。
  • Web应用(Laravel):RPS提升约3.8%,p99延迟降低1ms,收益很小。

避坑指南:别让JIT拖后腿

  1. opcache.file_cache冲突:如果同时开启opcache.file_cache和JIT,可能导致缓存文件损坏。建议关闭file_cache或设置opcache.file_cache_only=0
  2. JIT buffer_size设置:太小(<32M)导致频繁编译,太大(>256M)浪费内存。推荐64M-128M。
  3. tracing vs function:tracing适合长运行脚本(如CLI任务),function适合短请求(Web)。但实测差异不大,建议默认tracing。
  4. 预热问题:JIT需要运行几次后才生效。生产环境建议用php -d opcache.jit=function script.php预热,或使用OPcache预加载。
  5. 兼容性:某些扩展(如xdebug)会禁用JIT。检查php -i | grep jit确认状态。

最佳实践:什么时候开JIT?

  • CLI脚本:计算密集型(图像处理、数据转换)强烈推荐开启,配置tracing模式,buffer_size=128M。
  • Web应用:如果业务逻辑复杂(大量循环、递归),可以开启,但收益有限。建议先压测,如果RPS提升<5%,不如优化数据库查询。
  • 微服务/API网关:如果路由匹配和中间件处理是瓶颈,JIT可能有用。但通常瓶颈在I/O,JIT帮不上忙。

一句话:JIT是锦上添花,不是雪中送炭。先优化架构和SQL,再考虑JIT。

IT搬运工

专注技术分享,坚持原创深度内容。

分类
链接
订阅

RSS 订阅关注最新文章

© 2026 IT搬运工 · 站点地图 · 鄂ICP备19007640号-3