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-development
をphp.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
とするだけ。
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();