PHP7.4已經發布,釋出了很多新特性,其中有一項功能比較吸引人,那就是預載入功能,可以將檔案提前載入到記憶體當中,據說可以提升PHP效能,但是究竟是不是能提升,能提升多少,我們可以做一個實驗來測試下。
思路
預載入的原理就是將類提前載入到記憶體中,這種提升在fpm場景下最適合,所以筆者做了以下幾個角度的測試。
- 速度測試:比較php7.4預載入、php7.4無預載入、php7.3三種環境下,同一份檔案訪問的表現
- 空間測試:也就是上面三種環境下記憶體使用情況
- CPU使用的情況可以忽略,因為下面的測試使用了docker,已經將cpu使用率降低到了25%
工具
-
php專案:
1) 在www目錄下面,預設訪問的是index.php檔案,裡面引用了www/Dog目錄下的三個檔案(增加檔案讀取操作);
2) 為了驗證預載入確實讀取類到了記憶體中,增加了dog類 -
使用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
-
增加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記憶體,至於是不是已經預載入了類,還不能下結論
下面採用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 |
總結
- php7.4開啟預載入,效能確實提升了很多,原因就是大幅度減少了檔案讀取的時間
- 未開啟預載入的情況下,php7.3和php7.4效能差距不大
- php7.4開啟了預載入後,但是並沒有預載入特定檔案(Cat類)效能居然也有提升,原因還不得而知???
- 從第二個測試來看php7.4開啟預載入之後,類確實載入到了記憶體中,這就是提升效率的關鍵,但是在實際專案中,這個特性可能會因為不熟悉特性重複定義類導致專案報錯掛掉(潛在的風險)
- 沒有做關於laravel的測試,因為不想做了,原理差不多
- 在實際應用中,應該對經常使用的類進行熱載入,而不要全部載入,參考下面第二個文獻