zoco

晚到的PHP8测评

2020-07-14


6月25号php 8 alpha 1发布,7月9号 php 8 alpha 2发布,一般alpha 2是一个稍微能用的版本,所以周末测评了一下php8 JIT到底是个什么?

测试方式部分参考鸟哥的blog PHP 8新特性之JIT简介 - 风雪之隅

先看一下结果:

JIT不开启的情况下

php -d opcache.jit_buffer_size=0 Zend/bench.php
simple             0.025
simplecall         0.012
simpleucall        0.012
simpleudcall       0.012
mandel             0.135
mandel2            0.211
ackermann(7)       0.082
ary(50000)         0.012
ary2(50000)        0.010
ary3(2000)         0.186
fibo(30)           0.283
hash1(50000)       0.039
hash2(500)         0.041
heapsort(20000)    0.089
matrix(20)         0.110
nestedloop(12)     0.096
sieve(30)          0.045
strcat(200000)     0.019
------------------------
Total              1.419

JIT开启的情况下:

php -d -d opcache.jit_buffer_size=64M -d opcache.jit=1205 Zend/bench.php
simple             0.001
simplecall         0.000
simpleucall        0.000
simpleudcall       0.000
mandel             0.005
mandel2            0.006
ackermann(7)       0.010
ary(50000)         0.005
ary2(50000)        0.004
ary3(2000)         0.011
fibo(30)           0.027
hash1(50000)       0.027
hash2(500)         0.018
heapsort(20000)    0.011
matrix(20)         0.011
nestedloop(12)     0.006
sieve(30)          0.004
strcat(200000)     0.009
------------------------
Total              0.155

还有不打开Opcache的情况下:

php Zend/bench.php
simple             0.051
simplecall         0.017
simpleucall        0.083
simpleudcall       0.089
mandel             0.506
mandel2            0.409
ackermann(7)       0.095
ary(50000)         0.012
ary2(50000)        0.010
ary3(2000)         0.187
fibo(30)           0.367
hash1(50000)       0.040
hash2(500)         0.041
heapsort(20000)    0.097
matrix(20)         0.122
nestedloop(12)     0.093
sieve(30)          0.063
strcat(200000)     0.018
------------------------
Total              2.299

不开启Opcache : 2.299s 开启Opcache不开启JIT情况下:1.419s 开启Opcache且开启JIT情况下:0.155s

开启JIT情况下是不开启JIT情况下的接近9.15倍,多次测试这个值稳定在8倍到10倍之间。

业务表现如何?

为了接近我们的业务,所以在公司业务框架下进行测试

环境

aliyun centos 6.9

php7.test.com php-fpm一个进程 php8.test.com php-fpm一个进程

Mpf两个接口

/v1/hello/index1

public function index1() {
    $this->output('123');
}

/v1/hello/index2

public function index2() {
    $a = 0;
    for ($i = 0; $i < 1000000; $i++)
        $a++;

    $this->output($a);
}

我们压测一下

php7 计算少情况

wrk -c36 -d 5s -t12 https://php7.test.com/v1/hello/index1
Running 5s test @ https://php7.test.com/v1/hello/index1
  12 threads and 36 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   432.97ms   76.00ms 527.38ms   92.17%
    Req/Sec     8.38      5.36    20.00     63.85%
  396 requests in 5.09s, 121.43KB read
Requests/sec:     77.78
Transfer/sec:     23.85KB

php7 计算多情况

wrk -c36 -d 5s -t12 https://php7.test.com/v1/hello/index2
Running 5s test @ https://php7.test.com/v1/hello/index2
  12 threads and 36 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.02s   569.99ms   1.96s    57.14%
    Req/Sec     3.18      3.43    10.00     80.88%
  70 requests in 5.03s, 21.60KB read
  Socket errors: connect 0, read 0, write 0, timeout 42
Requests/sec:     13.91
Transfer/sec:      4.29KB

php8 JIT开启计算少情况

wrk -c36 -d 5s -t12 https://php8.test.com/v1/hello/index1
Running 5s test @ https://php8.test.com/v1/hello/index1
  12 threads and 36 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    34.48ms    4.34ms  95.45ms   87.87%
    Req/Sec    84.61     13.36   121.00     85.28%
  5083 requests in 5.03s, 1.67MB read
Requests/sec:   1010.55
Transfer/sec:    340.43KB

php8 JIT开启计算多情况

wrk -c36 -d 5s -t12 https://php8.test.com/v1/hello/index2
Running 5s test @ https://php8.test.com/v1/hello/index2
  12 threads and 36 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    97.84ms    4.97ms 159.50ms   92.12%
    Req/Sec    30.27      4.42    50.00     86.50%
  1814 requests in 5.07s, 614.71KB read
Requests/sec:    357.76
Transfer/sec:    121.23KB

php8 JIT关闭计算少情况

wrk -c36 -d 5s -t12 https://php8.test.com/v1/hello/index1
Running 5s test @ https://php8.test.com/v1/hello/index1
  12 threads and 36 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    38.10ms    6.47ms 239.60ms   94.01%
    Req/Sec    77.50     12.76   110.00     89.63%
  4622 requests in 5.04s, 1.52MB read
Requests/sec:    916.22
Transfer/sec:    308.65KB

php8 JIT关闭计算多情况

wrk -c36 -d 5s -t12 https://php8.test.com/v1/hello/index2
Running 5s test @ https://php8.test.com/v1/hello/index2
  12 threads and 36 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   766.16ms  181.30ms 887.08ms   88.37%
    Req/Sec     6.25      5.36    20.00     91.36%
  215 requests in 5.09s, 72.86KB read
Requests/sec:     42.22
Transfer/sec:     14.31KB

发现计算少情况下php8JIT是php7性能的13倍,而且计算越多优化越明显,计算多情况下php8JIT是php7性能的25.7倍。

但是有一个问题我觉得很神奇php8无JIT计算少的情况居然也优化了很多,我以为是测试方向的问题,但是经过多次论证,这个数据是准确的,有时间想找一下这里的优化点是什么。

编译过程

吐槽:php手动编译越来越麻烦了,编译了2个小时才编译完,踩了N个坑,为了让大家多写几个需求,把坑分享出来

环境

aliyun centos 6.9。

php源码编译

wget https://downloads.php.net/~carusogabriel/php-8.0.0alpha2.tar.gz

tar -zxf php-8.0.0alpha2.tar.gz

cd php-8.0.0alpha2

./configure --prefix=/yourdir/php8 --with-config-file-path=/yourdir/php8/etc --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --enable-fpm --enable-static --enable-sockets --with-zip --enable-calendar --enable-bcmath --enable-mbstring --with-zlib --with-iconv=/usr/local/libiconv --enable-gd --enable-mbstring --with-freetype --with-mysql-sock=/tmp/mysql.sock --disable-ipv6 --enable-debug --with-openssl --enable-opcache

这里一般都是makefile生成失败的,后面有生成失败的例子,生成成功后

make -j 8

make install

cp php.ini-production /yourdir/php8/etc/php.ini

配置php.ini

记住一定要把opcache.ini旧的配置也写上,JIT说到底还是对Opcache的优化。

zend_extension=opcache.so
opcache.enable=1

; 命令行测试的话这里一定要打开
opcache.enable_cli=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=300
opcache.fast_shutdown=1
opcache.enable_file_override = 1
opcache.blacklist_filename = /etc/php.d/opcache.blacklist

; 这里就是新的jit的配置
opcache.jit=1205
opcache.jit_buffer_size=64M

configure失败解决方法

这里解决./configure 失败的一些问题

问题一
No package 'sqlite3' found

解决办法

wget https://www.sqlite.org/2020/sqlite-autoconf-3320300.tar.gz

tar -zxf sqlite-autoconf-3320300.tar.gz

cd sqlite-autoconf-3320300

./configure --prefix=/usr/local/lib/sqlite-3.32.0

make CFLAGS="-g -O2 -DSQLITE_ENABLE_COLUMN_METADATA"

make install

export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/sqlite-3.32.0/lib/pkgconfig"

注意

直接这样是不行的,yum仓库里的版本太低。

yum install sqlite-devel 

问题二

configure: error: Please reinstall the iconv library.

解决办法

wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz

tar -zxf libiconv-1.14.tar.gz

cd libiconv-1.14

./configure 

make 

make install

问题三

No package 'oniguruma' found

同样yum也是不行的,版本太低。

yum install oniguruma-devel 

解决办法

wget https://github.com/kkos/oniguruma/archive/v6.9.5_rev1.tar.gz

tar -zxf v6.9.5_rev1.tar.gz

cd oniguruma-6.9.5_rev1/ 

autoreconf -vfi

./configure --prefix=/usr/local/lib/oniguruma-6.9.5

make 

make install

export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/oniguruma-6.9.5/lib/pkgconfig"

问题四

No package 'libzip' found

解决办法

wget https://libzip.org/download/libzip-1.7.2.tar.gz

tar -zxf libzip-1.7.2.tar.gz

cd libzip-1.7.2

cmake3 -DCMAKE_INSTALL_PREFIX=/usr/local/lib/libzip-1.7.2

make 

make install

export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/libzip-1.7.2/lib/pkgconfig"

Enjoy php 8 & JIT !