LoginSignup
24
17

More than 5 years have passed since last update.

PHP 7.1でOPcacheがすごい速くなってた

Last updated at Posted at 2016-12-08

去る12/1(日本時間12/2)にPHP 7.1.0が無事リリースされましたね!みなさんビルドしてみましたか?

そんな中、PHP Classesの記事「PHP Performance Evolution 2016 from PHP 5, PHP 7.0, PHP 7.1 and PHP 8/Next」にPHP 7.0から7.1で結構な性能改善があったと書いてあったので、追試してみたら本当だったという話を紹介します。

記事の概要

上記の記事ではPHP 5.6→7.0での性能改善が大きかったこと、7.0→7.1でもかなりの性能改善があったこと、PHP 8.0になるであろうJITコンパイル実装も現時点でかなり速いことなどが紹介されています。

このうち1番目と3番目は既に知られている内容だと思いますが、2番目は筆者は初耳だったので、手元の環境で確かめてみました。

ベンチマーク(OPcacheなし)

手元の環境はMac OS X 10.11(El Capitan)、PHP 7.0.13およびPHP 7.1.0はphp-buildで自前コンパイルしたものです。

PHPソースコードに付属のbench.phpで実験してみたところ、次のような結果が得られました。

PHP 7.0.13 PHP 7.1.0
simple 0.034 0.035
simplecall 0.011 0.011
simpleucall 0.035 0.035
simpleudcall 0.038 0.037
mandel 0.139 0.137
mandel2 0.146 0.142
ackermann(7) 0.034 0.032
ary(50000) 0.009 0.008
ary2(50000) 0.005 0.007
ary3(2000) 0.081 0.069
fibo(30) 0.129 0.122
hash1(50000) 0.013 0.012
hash2(500) 0.012 0.011
heapsort(20000) 0.040 0.035
matrix(20) 0.037 0.032
nestedloop(12) 0.068 0.068
sieve(30) 0.022 0.024
strcat(200000) 0.006 0.006
Total 0.861 0.822

確かにPHP 7.1.0の方が速いものの、テストによってはほとんど差が見られず、全体で見ると5%程度の改善にとどまっていることがわかります。これだけ見ると、性能改善は一休みかな?と思ってしまいそうですし、筆者もそういう印象を持っていました。

ベンチマーク(OPcacheあり)

ところが、上の記事によればPHP 7.1.0ではOPcacheの性能改善が大きかったようです。CLI版ではOPcacheはデフォルトで無効なので、PHPのコマンドラインオプションに-dopcache.enable_cli=1をつけて、OPcacheありのときの性能を比較してみたのが以下の表です。

PHP 7.0.13 PHP 7.1.0
simple 0.025 0.018
simplecall 0.008 0.007
simpleucall 0.033 0.007
simpleudcall 0.032 0.009
mandel 0.121 0.053
mandel2 0.138 0.076
ackermann(7) 0.030 0.028
ary(50000) 0.008 0.006
ary2(50000) 0.006 0.007
ary3(2000) 0.076 0.060
fibo(30) 0.102 0.096
hash1(50000) 0.013 0.012
hash2(500) 0.012 0.012
heapsort(20000) 0.036 0.029
matrix(20) 0.034 0.029
nestedloop(12) 0.048 0.043
sieve(30) 0.024 0.014
strcat(200000) 0.006 0.006
Total 0.753 0.512

OPcacheを有効にしてみると、両者の差は歴然です。全体で見ると30%の改善、テストによっては倍以上の性能になっているものもチラホラあります。

opcodeを確認してみた

PHP 7.1.0のOPcache最適化後のopcodeを確認してみたところ、たとえばsimpleucall()などは不要な関数呼び出しをばっさり削っており、通常のアプリケーションではあまり参考にならない結果だと感じました。

function hallo($a) {
}

function simpleucall() {
  for ($i = 0; $i < 1000000; $i++)
    hallo("hallo");
}
$ phpdbg -dopcache.enable_cli=1 -p'simpleucall' Zend/bench.php
function name: simpleucall
L28-31 simpleucall() /Users/hnw/src/php/php-7.1.0/Zend/bench.php - 0x10d2be240 + 6 ops
 L29   #0     QM_ASSIGN               0                                         $i
 L29   #1     JMP                     J3
 L29   #2     PRE_INC                 $i
 L29   #3     IS_SMALLER              $i                   1000000              ~0
 L29   #4     JMPNZ                   ~0                   J2
 L31   #5     RETURN                  null
[Script ended normally]

たしかに、このコードなら関数呼び出しを削っても挙動は変わりません。どうせならループごと削れるのでは?という気もしますが、ループは律儀に回してくれるようです。

一方で、たとえばsieve()(エラトステネスのふるい)が高速になった理由はパッと見ではわかりませんでした。

このPHP 7.1.0でのOPcacheの性能改善が実アプリケーションでも有効かどうかはまだわかりませんが、もし高速になるなら嬉しいニュースだと言えそうです。続報が楽しみですね。

24
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
17