PHP7.4 Preload 效能測試

Lingkong發表於2019-12-11

PHP7.4已經發布,釋出了很多新特性,其中有一項功能比較吸引人,那就是預載入功能,可以將檔案提前載入到記憶體當中,據說可以提升PHP效能,但是究竟是不是能提升,能提升多少,我們可以做一個實驗來測試下。

思路

預載入的原理就是將類提前載入到記憶體中,這種提升在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. 在實際應用中,應該對經常使用的類進行熱載入,而不要全部載入,參考下面第二個文獻

參考文獻

  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

相關文章