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 协议》,转载必须注明作者和本文链接
本帖由系统于 4年前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 14

支持newbee

4年前 评论

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

4年前 评论
Lingkong (楼主) 4年前
yybawang

恭喜OG

4年前 评论
Epona

楼上一堆Dota战队什么梗?

4年前 评论

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

4年前 评论
Lingkong (楼主) 4年前
Lingkong (楼主) 4年前
captain2021 (作者) 4年前
Lingkong (楼主) 4年前
captain2021 (作者) 4年前
Lingkong (楼主) 4年前
pi_phq 4年前

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

4年前 评论
Lingkong (楼主) 4年前

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

4年前 评论
Lingkong (楼主) 4年前
huangzhhui (作者) 4年前
Lingkong (楼主) 4年前
Lingkong (楼主) 4年前

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

4年前 评论

//打印所有文件名,包括路径
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,麻烦指导下,非常感谢

4年前 评论
Phor

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

4年前 评论
游离不2

preload 不适合用 laravel 项目

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
1
粉丝
1
喜欢
33
收藏
23
排名:917
访问:6710
私信
所有博文
博客标签
社区赞助商