PHP7.4 Preload 性能测试

PHP7.4 Preload 功能测试

PHP7.4已经发布,发布了很多新特性,其中有一项功能比较吸引人,那就是预加载功能,可以将文件提前加载到内存当中,据说可以提升PHP性能,但是究竟是不是能提升,能提升多少,我们可以做一个实验来测试下。

 先上github地址     https://github.com/linkkong/php7.4-preload-test

思路

预加载的原理就是将类提前加载到内存中,这种提升在fpm场景下最适合,所以笔者做了以下几个角度的测试。

  1. 速度测试:比较php7.4预加载、php7.4无预加载、php7.3三种环境下,同一份文件访问的表现
  2. 空间测试:也就是上面三种环境下内存使用情况
  3. CPU使用的情况可以忽略,因为下面的测试使用了docker,已经将cpu使用率降低到了25%

工具

  1. php项目:

    1) 在www目录下面,默认访问的是index.php文件,里面引用了www/Dog目录下的三个文件(增加文件读取操作);
    2) 为了验证预加载确实读取类到了内存中,增加了dog类

  2. 使用docker-compose编排了三个php环境分别是php7.4预编译、php7.4普通、php7.3普通

      php74:
        image: php:7.4-fpm
        volumes:
          - ./www/:/var/www/html/:cached
          - ./php/preload.ini:/usr/local/etc/php/conf.d/preload.ini
        expose:
          - 9000
        deploy:
          resources:
            limits:
              cpus: '0.25'
              memory: 150M
      php741:
        image: php:7.4-fpm
        volumes:
          - ./www/:/var/www/html/:cached
        expose:
          - 9000
        deploy:
          resources:
            limits:
              cpus: '0.25'
              memory: 150M
      php73:
        image: php:7.3.9-fpm
        volumes:
          - ./www/:/var/www/html/:cached
        expose:
          - 9000
        deploy:
          resources:
            limits:
              cpus: '0.25'
              memory: 150M

    预加载比普通多了一个预加载的配置文件,把www/Dog里的文件进行了opcache_compile_file

    参考php/preload.ini和www/preload.php

  3. 增加nginx配置,参考nginx/conf.d/default.conf

    环境 Host
    php7.4预加载 http://localhost:8000/
    php7.4无加载 http://localhost:8001/
    php7.3普通 http://localhost:8002/

测试

打开2个窗口,分别执行下面的命令,不要关闭

      //监控docker容器的cpu使用和内存使用
      docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"

      //启动所有容器,必须使用--compatibility参数,否则CPU内存限制无效
      docker-compose --compatibility up

运行起环境后可以看到,php74_1是预加载环境,php741_1是无预加载环境,php73_1是php7.3环境,php7.4预加载环境已经比无预加载环境多使用了0.08Mib内存,至于是不是已经预加载了类,还不能下结论
PHP7.4 Preload 性能测试
下面采用ab来进行简单的压测,并用每秒请求数来进行对比

      ab -c 10 -n 1000 http://localhost:8000/

测试index.php

测试7.4预加载、7.4无预加载、7.3三种环境的表现

环境和地址 第1次 第2次 第3次 第4次 第5次
7.4预加载;http://localhost:8000/ 268 367 410 345 359
7.4无预加载;http://localhost:8001/ 153 180 160 137 190
7.3;http://localhost:8002/ 154 110 126 134 131

测试dog.php

dog.php包含了Dog文件夹下的内容,主要测试dog类,是否已经在内存中。用curl访问即可,或者浏览器打开

环境和地址 运行结果
7.4预加载;http://localhost:8000/dog.php Cannot declare interface AnimalInterface, because the name is already in use in /var/www/html/dog.php
7.4无预加载;http://localhost:8001/dog.php It is runningWang! Wang!
7.3;http://localhost:8002/dog.php It is runningWang! Wang!

测试cat.php

cat.php包含cat类,就是将dog类改了下名字全部放到了cat.php文件中,减少文件读写;主要测试在文件读写次数一致的情况下程序的表现

环境和地址 第1次 第2次 第3次 第4次 第5次
7.4预加载;http://localhost:8000/cat.php 334 305 337 395 366
7.4无预加载;http://localhost:8001/cat.php 282 201 221 213 269
7.3;http://localhost:8002/cat.php 219 247 216 295 254

总结

  1. php7.4开启预加载,性能确实提升了很多,原因就是大幅度减少了文件读取的时间
  2. 未开启预加载的情况下,php7.3和php7.4性能差距不大
  3. php7.4开启了预加载后,但是并没有预加载特定文件(Cat类)性能居然也有提升,原因还不得而知???
  4. 从第二个测试来看php7.4开启预加载之后,类确实加载到了内存中,这就是提升效率的关键,但是在实际项目中,这个特性可能会因为不熟悉特性重复定义类导致项目报错挂掉(潜在的风险)
  5. 没有做关于laravel的测试,因为不想做了,原理差不多
  6. 在实际应用中,应该对经常使用的类进行热加载,而不要全部加载,参考下面第二个文献

最终还是做了Laravel的测试,见图

laravel项目是6.5版本,只修改了route/web.php,把默认返回值改成了一个json,其他均未修改

貌似php7.4只要开启preload,不需要配置preload文件也能加快访问速度(原理未知,可能是自动缓存了,如果是自动缓存,那么后期更新项目就需要重启fpm,不然会有问题),所以我在www目录下面放入了一个laravel项目,然后用ab 进行了压测,压测结果特别低是因为对容器的CPU和内存做了限制。

从2,3图来看,没有开启preload的php7.4与php7.3性能相差无几,但是开启了preload的php7.4,提升还是很明显的,降低了非常多的文件读取性能消耗

PHP7.4 Preload 性能测试


Laravel第二次测试

经过韩天峰大佬指正,php7.3和php7.4也应该同时开启opcache,上面的实验提升很大其实是opcache的功劳。

PHP7.4 Preload 性能测试

对laravel的vendor/laravel文件进行了preload,再次做了实验,得到如上的数据,相比较两个php7.4是否开启preload还是有差距的,但是php7.3+opcache的实验数据居然跟php7.4+preload性能接近,这个还有点想不通,需要进一步测试。也可能是laravel框架和php7.4并不适配,亦或是opcache开启的参数没有调优;

存在的问题

  1. php7.3+opcache的实验数据居然跟php7.4+preload性能接近

可以改进的地方

  1. fpm容器没有调优,没有设置fpm连接数等
  2. opcache参数没有调优,只有 opcache.enable = 1;opcache.enable_cli = 1
  3. 没有测试数据库链接等场景,也没有评测其他框架

最后

php7.4开启preload的性能依据官方评测,提升在10%左右,其实并不是很大了,相对开启opcache,收益较小,而且还跟缓存的文件有关。所以这个实验也证明了,php7以上的版本,请务必开启opcache,因为带来的提升真的很大。

参考文献

  1. Composer: How it should preload in PHP 7.4
  2. 国外同行做的测试,可能是基于laravel
  3. Preloading in PHP 7.4
  4. 在 Docker Compose file 3 下限制 CPU 與 Memory
php
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 1个月前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 12

支持newbee

1个月前 评论

测试框架才有意义 框架预加载的东西才多

1个月前 评论
Lingkong (楼主) 1个月前
pi_phq 1个月前
yybawang

恭喜OG

1个月前 评论
Epona

楼上一堆Dota战队什么梗?

1个月前 评论
NiZerin

非常有意思的测试~

1个月前 评论
hxd

不科学啊,不需要配置就自动 preload?? 楼主动手能力强大

1个月前 评论
Lingkong (楼主) 1个月前
Lingkong (楼主) 1个月前
hxd (作者) 1个月前
Lingkong (楼主) 1个月前
hxd (作者) 1个月前
Lingkong (楼主) 1个月前
pi_phq 1个月前

很棒!思路清晰,可变量控制较好,结果值得参考。

1个月前 评论
Lingkong (楼主) 1个月前

2 rps 提升到 26 rps ??????这数据是认真的??????

1个月前 评论
Lingkong (楼主) 1个月前
huangzhhui (作者) 1个月前
Lingkong (楼主) 1个月前
Lingkong (楼主) 1个月前

遇到高并发,还是得上swoole了

1个月前 评论

//打印所有文件名,包括路径
foreach ($filenames as $value) {
if (strpos($value, '.php') !== false) {
opcache_compile_file($file);
}
// echo $value . "
";
}

楼主,你好,你的 github 上的 laravel_preload.php 这个文件的这段代码的 opcache_compile_file($file); $file 这个变量不存在,请问如何实现 laravel 框架的 preload,麻烦指导下,非常感谢

1个月前 评论
Phor

你这关系挺硬啊,都能得到大佬的指点。感觉你这几个测试的讲述有点粗糙,期待你的后续测试数据!支持一下 :+1:

4周前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
未填写
文章
1
粉丝
1
喜欢
26
收藏
12
排名:848
访问:2554
私信
所有博文
博客标签