首頁 >後端開發 >PHP8 >PHP 8新特性之JIT對PHP應用效能的影響

PHP 8新特性之JIT對PHP應用效能的影響

藏色散人
藏色散人轉載
2020-10-30 16:25:105652瀏覽

推薦:《PHP8教程

前言

即將發布的PHP 8 最受大家關注的新特性就是引入了對JIT 的支持,我已經簡單介紹了JIT 是什麼,以及與Opcache 的區別,這裡簡單總結下:

  • JIT 是在Opcache 優化的基礎上結合Runtime 資訊將字節碼編譯為機器碼快取起來
  • 現有的Opcache 最佳化不受任何影響,並且PHP 的JIT 是在Opcache 中提供的
  • JIT 不是對Opcache 替代,而是增強,在啟用JIT 的情況下,如果Zend 底層發現特定字節碼已經編譯為機器碼,則可以繞過Zend VM 直接讓CPU 執行機器碼,從而提高程式碼效能。

看起來很高大上,不過JIT 主要針對CPU 密集型操作優化效果明顯,而目前主流的PHP Web 應用都是IO 密集型操作,那麼PHP 8 引入的JIT 對這些Web應用的性能有沒有提升呢?為此,特地編譯安裝了 PHP 8 Alpha 版本,並分別對命令列應用(CPU 密集型操作)和 Laravel 應用(IO 密集型操作)進行了簡單的基準測試來探個究竟。

準備一個Ubuntu 虛擬機器

#:PHP 的JIT 只能在X86 架構下生效,所以使用Intel CPU 的PC、Mac、Linux 環境均可支援。

由於目前 PHP 8 還沒有正式發布,只能下載原始碼編譯安裝,所以需要準備一個 Linux 環境作為測試環境。不少同學跟我反映沒怎麼在Windows 上示範過操作流程,所以今天我特地選擇在Windows 10 專業版中透過WSL 來安裝Ubuntu 18.04 作為示範環境,這個比透過Virtual Box 或者VMWare 安裝虛擬機簡單多了,不得不說,從Windows 10 開始,對開發者越來越友善了,雖然比起Mac 還是有些距離,畢竟Mac 是原生的類Unix 系統。

言歸正傳,安裝WSL 版Ubuntu 虛擬機Windows 官方提供了相應的文檔:Windows Subsystem for Linux Installation Guide for Windows 10,照著做就好了,非常簡單,在Windows商店下載安裝後,就可以點選啟動按鈕啟動這個Ubuntu 虛擬機器了:

#開啟後的介面是這樣的,看起來和一個終端視窗差不多:

這個虛擬機使用起來的體驗比傳統的虛擬機要簡單一些,例如直接可以呼叫Windows 宿主機的程序,例如VS Code,在虛擬機中透過Nginx 管理的Web 應用程式也可以直接從Windows 宿主機的瀏覽器訪問,無需配置連接埠映射,所以用來作為本機Linux 測試開發環境很方便。

當然,如果你不想嚐鮮的話,使用傳統的虛擬機器或原生的 Ubuntu 系統都可以。

示範專案初始化

接下來,我們需要透過上面開啟的終端機視窗在這個Ubuntu 虛擬機器中安裝Nginx,以及PHP、Composer,透過以下幾個指令就可以搞定了:

sudo apt install nginx
sudo apt install php php-zip php-mbstring
sudo apt install composer

然後透過Composer 在Nginx 預設Web 根目錄/var/www 目錄下安裝用於示範的Laravel Web 專案(下載速度慢可以設定Composer 全域鏡像):

sudo composer create-project --prefer-dist laravel/laravel blog 6.* -vvv

初始化完成後,可以透過php artisan serve 測試下這個項目存取是否正常。這裡就不示範了。

編譯安裝PHP 8 測試版

完成上述準備工作後,就可以開始PHP 8 測試版本的編譯安裝了,首先,我們從Github 下載PHP 8測試版本原始碼(PHP 官網原始碼套件下載太慢):

wget https://github.com/php/php-src/archive/php-8.0.0alpha2.tar.gz

解壓縮並進入原始碼根目錄:

tar zxvf php-8.0.0alpha2.tar.gz
cd php-8.0.0alpha2

開始編譯安裝流程:

// 1、安装相关依赖库
sudo apt install -y pkg-config build-essential autoconf bison re2c libxml2-dev \
libsqlite3-dev libssl-dev libcurl4-openssl-dev libpng-dev libonig-dev libzip-dev

// 2、生成 configure 文件
./buildconf --force

// 3、配置构建流程
./configure --prefix=/usr/local/php8 \
--with-config-file-path=/usr/local/php8 \
--enable-mbstring  \
--enable-ftp  \
--enable-gd   \
--enable-mysqlnd \
--enable-pdo   \
--enable-sockets   \
--enable-fpm   \
--enable-xml  \
--enable-soap  \
--enable-pcntl   \
--enable-cli   \
--enable-json  \
--enable-tokenizer \
--enable-ctype \
--enable-bcmath  \
--with-openssl  \
--with-pear   \
--with-zlib  \
--with-iconv  \
--with-curl  \
--with-zip

// 4、构建
make

// 5、安装
sudo make install

最後一步執行成功後,會有PHP 8 安裝成功的提示文本,你也可以透過以下指令驗證安裝成功:

目前PHP 8 被安裝到了/usr/local /php8 這個目錄下。

初始化設定檔

編譯安裝的PHP 8 需要自行拷貝和設定設定文件,我們先將基礎設定檔php.ini 從原始碼目錄拷貝到PHP 的安裝目錄:

sudo cp php.ini-production /usr/local/php8/php.ini

由於JIT 是在Opcache 擴展中提供的,所以需要先啟動這個擴展,打開/usr/local/php8/php.ini,取消如下組態項目的註解(刪除前面的分號即可):

zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1

然後來初始化PHP-FPM 的設定檔。

先把php8.0-fpm 二進位檔案拷貝到/etc/init.d 目錄下(還是在php-8.0.0alpha2原始碼目錄下操作):

sudo cp sapi/fpm/init.d.php-fpm /etc/init.d/php8.0-fpm
sudo chmod +x /etc/init.d/php8.0-fpm

进入 /usr/local/php8/etc 目录,初始化 PHP-FPM 配置文件:

cd /usr/local/php8/etc
sudo cp php-fpm.conf.default php-fpm.conf

通过 vim 编辑器打开 php-fpm.conf,修改如下配置项(同时取消前面的分号注释):

pid = /run/php/php8.0-fpm.pid

然后进入当前目录下的 php-fpm.d 子目录:

cd php-fpm.d
sudo cp www.conf.default www.conf

打开 www.conf,修改如下配置项(同时取消前面的分号注释):

user = www-data
group = www-data

listen = /run/php/php8.0-fpm.sock

listen.owner = www-data
listen.group = www-data
listen.mode = 0660

命令行应用基准测试

完成上述准备工作后,就可以正式开始测试工作了。

首先,我们来测试命令行应用,PHP 官方在源码中提供了一个基准测试文件,我们进入源码所在目录 php-8.0.0alpha2,通过如下命令测试不启动 JIT 情况下代码运行情况:

/usr/local/php8/bin/php -d opcache.jit_buffer_size=0 Zend/bench.php

运行结果如下(运行时间,单位为 s):

然后,再通过下面这条命令测试启动 JIT 的情况下命令行代码的运行情况:

/usr/local/php8/bin/php -d opcache.jit_buffer_size=64M -d opcache.jit=1205 Zend/bench.php

注:关于 opcache.jit_buffer_size 配置项比较好理解,而 opcache.jit 配置项对应配置值的每个数字代表不同含义,具体可以参考鸟哥的这篇博客:PHP 8 新特性之 JIT 简介,里面讲得非常详细,一般对于命令行应用,将该配置值配置为 1205,对于 Web 应用,配置为 1235 或者 1255。

最终运行结果如下:

可以看到,在 CPU 密集型操作的命令行应用中,启用 JIT 与不启用相比,耗时降低了接近 60%,性能提升了 2 倍

Web 应用基准测试

接下来,我们以 Laravel 演示项目为例,演示 PHP Web 应用中启用 JIT 与不启用性能有没有提升。

启动 PHP-FPM:

sudo /etc/init.d/php8.0-fpm start

在 Nginx 中配置一个新的虚拟主机(/etc/nginx/sites-available/blog):

server {
    listen 80;
    server_name blog.test;
    root /var/www/blog/public;

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

然后进入 /etc/nginx/sites-enable 目录,创建这个虚拟主机的软连接:

sudo ln -s /etc/nginx/sites-available/blog blog

启动 Nginx:

sudo service nginx start

在 Windows 系统的 C:\Windows\System32\drivers\etc\hosts 文件中添加虚拟域名与主机地址的映射:

127.0.0.1 blog.test

此时可以在 Windows 宿主机中通过浏览器访问对应的 Laravel 项目,表示部署成功:

然后,我们还是在 Windows 中,通过 ab 命令对 blog.test 首页进行压力测试(此时尚未启用 JIT):

ab -n 10 -c 10 http://blog.test/

注:-n 表示总请求数,-c 表示最大并发请求数。

测试结果如下,重点关注 RPS(每秒处理请求数):

PHP 8新特性之JIT對PHP應用效能的影響

最后,在 Ubuntu 虚拟机中,打开 PHP 8 的配置文件 /usr/local/php8/php.ini,在 Opcache 配置项下新增 JIT 配置:

opcache.jit=1235
opcache.jit_buffer_size=64M

配置完成后,重启 PHP-FPM 服务,再次回到 Windows 宿主机,通过 ab 命令对 http://blog.test 页面进行压力测试:

ab -n 10 -c 10 -s 60 http://blog.test/

注:-s 表示超时时间。

运行结果如下:

PHP 8新特性之JIT對PHP應用效能的影響

可以看到在 IO 密集型操作的 Web 应用中,启用 JIT 与不启用相比,性能不但没有提升,反而有 10% 左右的损耗,至少在 Laravel 应用中是如此。

小结

当然,这里的测试仅限于的 Ubuntu 虚拟机环境(Windows WSL 版,配置是 8C8G),并且我也只是将 JIT 参数调整为官方建议的参数,没有做更多的对比测试,但是可以肯定的是 JIT 对 CPU 密集型操作优化效果很好,对 Web 应用性能是否有提升,取决于你的环境和配置的调优,因此 JIT 对 IO 密集型操作应用的性能优化效果有限,更适用于 CPU 密集型操作场景的性能优化,比如图像处理、机器学习等。

以上是PHP 8新特性之JIT對PHP應用效能的影響的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:xueyuanjun.com。如有侵權,請聯絡admin@php.cn刪除