181
81

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHP8.0.0α1がリリースされたのでさっそくJITの威力を体感する(した)

Last updated at Posted at 2020-06-26

2020/06/25、PHP8.0.0α1がリリースされました
PHP8系の初のバージョンです。
ただし名前のとおりα版であり、まだまだ実環境で使えるものではありません。
今後は2020/08/04にフィーチャーフリーズ、即ち新機能の取り込みが終了し、その後はβやRCで徐々に完成度を高めながら、2020/11/26に正式版がリリースされる予定です。

そんなわけでPHP8の目玉、JITの性能を試してみることにしましょう。

今回はXAMPPに導入してWebサーバとして動かすことができなかったので、以下のベンチマークはコマンドラインで実行した結果となります。
きっとそのうちXAMPPも対応してくれるはず。

インストール

QA ReleasesからVS16 x64 Thread Safeのzipをダウンロード。
適当なディレクトリに解凍。
php.ini-developmentphp.iniにコピー。

php.iniを変更。
memory_limit = 1024Mにする
date.timezone = "Asia.Tokyo"にする
extension_dir = "ext"のコメントアウトを外す

ベンチマークの設定

デフォルトの設定
・上の『php.iniを変更』のまま。ほぼ初期状態。

opcache有効の設定
・『デフォルトの設定』に対して、以下を追加する。
zend_extension=opcache
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=0x7FFFBFFF

JIT有効の設定
・『opcache有効の設定』に対して、以下を追加する。
opcache.jit_buffer_size = 128M

ベンチマーク結果

プログラムは最後に載せておきますが、JITのRFCで使われていたマンデルブロ集合を計算するやつです。
使用したCPUはIntel i7-9700 3.00GHz。
測定結果の単位は秒です。

デフォルト opcache有効 JIT有効 参考7.4.7
0.814755 0.355585 0.106190 0.960383
0.818260 0.356907 0.106928 0.938955
0.822746 0.353799 0.106061 0.940920
0.817202 0.353423 0.106768 0.951347
0.819391 0.353574 0.106117 0.936791

本当かよ?????????

まずPHP7.4.7からPHP8にアップデートするだけで処理時間が1割削減されています。
ただでさえ新機能てんこ盛りだってのに、そのうえ速度も上がるとかどうなってるんだPHP8。

次いでopcacheを有効にすると処理時間が半分になります。

最後にJITを有効にしたら、処理時間がopcache有効状態の30%になりました。
30%縮まりました、ではありません。
なんだこれ。

ということで、JITを有効にするだけで、処理時間がPHP8デフォルト設定の13%になりました。
どういうことかというと、元々1分かかっていた処理が8秒で終わるようになります。
足枷を外したとかいうレベルじゃねーぞ。
これ本当に計算してるのか?
計算結果が固定値だから結果だけどこかに保存してるとかじゃないよな?

しかもこれ、opcacheやJITの設定はほぼ初期値で、とりあえず有効にしただけという状態ですからね。
チューニングすればさらに早くなることでしょう。
面倒なので今回はそこまでやってませんが。

プリロード

PHP7.4.0で入ったプリロードで更なる高速化を図ってみましょう。

opcache.preload="path/to/preload.php"を設定
preload.phpの中身はopcache_compile_file('path/to/mandelbrot.php');

Error Preloading is not supported on Windows

はい。

実はWindowsではプリロードを使えません。

PHP7.4.0リリース時点ではWindowsでもプリロードを使えていたのですが、その後PHP7.4.2で提供が中止されてしまいました。
実はWindowsのプリロードはASLRのせいで本当のプリロードじゃないんだとかいうことらしいですがよくわかりません。

そんなわけで*nix勢あとよろ。

感想

あくまでCPUだけをがりがり使うプログラムに対しての検証結果です。
ファイルやデータベースへのアクセスが多くなる一般的なプログラムについては、また異なる結果になるでしょう。
またLaravelなど普通のWebアプリがどの程度高速化されるかも、今回は調べられていません。

とはいえ、そうはいってもさすがにこの結果は驚異的です。
もはや環境を作れないので試していませんが、PHP5.6からPHP7で速度が倍以上になったという過去もあります。
全部合わせるとPHP8が処理にかかる時間はPHP5の5%とかです。
PHP8はもはや、PHP5時代とは別次元の速度を手にいれました。

ベンチマークプログラム

マンデルブロ集合を計算するやつのほぼコピペです。

実行はコマンドラインからpath/to/php8/php.exe path/to/mandelbrot.phpとするだけ。

mandelbrot.php
define("BAILOUT", 16);
define("MAX_ITERATIONS", 5000); // 1000だと早すぎたので

class Mandelbrot
{
    public function __construct()
    {
        $output = '';
        $d1 = microtime(1);
        for ($y = -39; $y < 39; $y++) {
            for ($x = -39; $x < 39; $x++) {
                if ($this->iterate($x/40.0, $y/40.0) == 0) {
                    $output .= '*';
                } else {
                    $output .= ' ';
                }
            }
            $output .= "\n";
        }
        $d2 = microtime(1);
        $diff = $d2 - $d1;
        echo $output; // 出力は最後にまとめた
        printf("\nPHP Elapsed %0.6f\n", $diff);
    }

    public function iterate($x, $y)
    {
        $cr = $y-0.5;
        $ci = $x;
        $zr = 0.0;
        $zi = 0.0;
        $i = 0;
        while (true) {
            $i++;
            $temp = $zr * $zi;
            $zr2 = $zr * $zr;
            $zi2 = $zi * $zi;
            $zr = $zr2 - $zi2 + $cr;
            $zi = $temp + $temp + $ci;
            if ($zi2 + $zr2 > BAILOUT) {
                return $i;
            }
            if ($i > MAX_ITERATIONS) {
                return 0;
            }
        }
    }
}

$m = new Mandelbrot();
181
81
4

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
181
81

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?