Quantcast
Channel: PHP8タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 521

【PHP8】JIT=on の Docker を触ってみたい人。爆速だったよ。

$
0
0

PHP8 で JIT が使えるようになるそうなので、ワクワクが止まりません。手軽に触れるイメージが Docker ないものか。

TL;DR

PHP8-ish(master = 一番 PHP8 に近い状態)の PHP をソースからコンパイルして JIT を有効にした Docker イメージを作ってみました。Mac 以外にもラズパイ3、ラズパイZero の Docker で動くようにしています。

Mac に標準インストールされている PHP7.1 と比較して 2〜3 倍近く速いです。(詳しくは TS;DR)

docker pull keinos/php8-jit:latest

使い方

docker run --rm -it keinos/php8-jit:latest

基本構文

docker run --rm -it keinos/php8-jit:latest [コマンド] [引数]
コマンド実行例
docker run --rm -it keinos/php8-jit:latest php -a
  • docker run で「コンテナの起動」
  • --rm で「終了後にコンテナを破棄(remove)」(ロングオプションなので -- です)
  • -it でシェル操作をコンテナとつなげる。
    • -i -t もしくはロングオプションの --interactive --tty と同じ意味です。つまり、コンテナの標準入出力とローカルの標準入出力を tty 経由でつなげ、コンテナのシェル操作をローカルのシェルから行えるようになります。これを忘れると、実行コマンド終了後に入力待ちにならず処理が終わりコンテナがシャットダウンしてしまいます。
  • keinos/php8-jit:latest で「コンテナの元となるイメージを指定」
  • php でランタイムを指定
  • -a

対話モードで実行

PHP対話モードで実行
$ # コマンドや引数の指定がない場合は対話モードで起動します(デフォルトの動作)
$ docker run --rm -it keinos/php8-jit:latest
Interactive shell

php > echo phpversion();
8.0.0-dev
php > exit
$
$ # コマンドが php -a の場合と同じ動作です。
$ docker run --rm -it keinos/php8-jit:latest php -a
Interactive shell

php > echo phpversion();
8.0.0-dev
php > exit
$

PHP コマンドの直接実行

PHPコマンドを直接実行
$ # php --version の実行
$ docker run --rm -it keinos/php8-jit:latest php --version
PHP 8.0.0-dev (cli) (built: Jul 19 2019 07:09:36) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.0-dev, Copyright (c), by Zend Technologies
$
$ # php -r で `echo "hoge", PHP_EOL;` のスクリプトを実行
$ docker run --rm -it keinos/php8-jit:latest php -r 'echo "hoge", PHP_EOL;'
hoge
$

コンテナ内から PHP を実行

コンテナ内のシェルから実行
$ # /bin/sh でコンテナ内の Bourne Shell(sh)シェルを起動
$ docker run --rm -it keinos/php8-jit:latest /bin/sh
/ $ # コンテナ内の sh シェルから php -v を実行
/ $ php -v
PHP 8.0.0-dev (cli) (built: Jul 19 2019 07:09:36) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.0-dev, Copyright (c), by Zend Technologies
/ $ 
/ $ # コンテナ内の sh シェルから`echo "hoge", PHP_EOL;` のスクリプトを php -r で実行
/ $ php -r 'echo "hoge", PHP_EOL;'
hoge
/ $ # シェルを抜けてコンテナを終了
/ $ exit
$

コンテナにファイルをマウントして実行

ファイルをマウントして実行
$ # ローカルのファイルを用意
$ ls
test.php
$ cat test.php
<?php

echo 'Hello World!', PHP_EOL;

$ # test.php をマウントして実行
$ docker run --rm \
>   -v $(pwd)/test.php:/app/test.php \
>   keinos/php8-jit:latest \
>   php /app/test.php
Hello World!
$

コンテナにディレクトリをマウントして実行

ディレクトリをマウントして実行
$ # ローカルのディレクトリを確認
$ ls
src
$ ls src
index.php     functions.inc.php
$ # src ディレクトリをマウントして実行
$ docker run --rm \
>   -v $(pwd)/src:/app \
>   -w /app \
>   keinos/php8-jit:latest \
>   php index.php
Hello World! from a function.
$

ビルド

Docker Hub から Pull せずにイメージをビルドしたい場合は、リポジトリを clone してビルドしてください。

$ # 適当な作業ディレクトリに移動
$ cd ~/
$ # リポジトリを clone
$ git clone https://github.com/KEINOS/Dockerfile-of-PHP8-JIT.git php8
$ # リポジトリに移動
$ cd $_
$ # Docker イメージのビルド
$ docker build --no-cache -t php8-jit .
...

インストール済みの PHP モジュール

2019/10/04 現在コンパイル&インストール済みのモジュールは以下の通りです。追加して欲しいモジュールがあれば、リポジトリの Issues にあげてください。(日本語でおk)

$ docker run --rm -it keinos/php8-jit:latest php -m
[PHP Modules]
Core
ctype
curl
date
dom
FFI
fileinfo
filter
ftp
gd
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
pcntl
pcre
PDO
pdo_sqlite
Phar
posix
readline
Reflection
session
SimpleXML
soap
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
Zend OPcache
zlib

[Zend Modules]
Zend OPcache

TS;DR(リリースまで JIT 我慢できない)

上記の Qiita 記事を読んでワクワクが止まらず、触ってみたい欲にかられました。

非公式ながらも PHP 8.0.0 Dev 版の Docker イメージはあるのですが、残念ながらデフォルトで JIT が有効になっておらず、mb_string なども一緒にコンパイルされていません。

また、PHP 8.0.0 とは言っても最新の master ブランチを使っているので一番 PHP8 に近いバージョンというだけのようですが、それでも一応 master は PHP8 用として進められているようです。

JIT の正式採用は PHP8 からと決定されたので、この Docker イメージは「いちはやく JIT の挙動をみるための目的で作成された」とのこと。どうやら JIT を有効にした場合に PHP のコンパイルに難があるようで、それらの注意点をまとめた記事をベースに作られたそうです。

測定

そこで、上記記事を参考に JIT および mb_string を有効にした PHP8 の Dockerfile を作ってみたので、測定してみました。自分でコンパイルしてみたいかたは、リポジトリclone して、docker build してみてください。

測定は「フィボナッチ数」の算出と「ズンドコキヨシ」ループです。リポジトリには Zend の ベンチマークも置いてあります。

テストコード

比較用スクリプト

実行結果

  • 同じ PHP8 同士でも JIT を有効にするだけで 2〜3 倍近く速なった。
  • Docker で PHP を使うなら 7.3.6 がバランス的(速度・安定的に)にベストと思われる。
PHPバージョン 実行環境 実測値(フィボナッチ数) 
PHP 5.6.40 Docker 1.4402780532837
PHP 7.1.23 ローカル実行 0.3146538734436
PHP 7.1.23 Docker 0.57761478424072
PHP 7.3.6 Docker 0.23189496994019
PHP 8.0.0-dev Docker
(JIT=off)
0.24225091934204
PHP 8.0.0-dev Docker
(JIT=on)
0.093664884567261
PHPバージョン 実行環境 実測値(ズンドコキヨシ) 
php 5.6.40 Docker 2.3430778980255
PHP 7.1.23 ローカル実行 0.75591492652893
php 7.1.23 Docker 1.3070819377899
php 7.3.6 Docker 0.60567092895508
php 8.0.0-dev Docker
(JIT=off)
0.6335301399231
php 8.0.0-dev Docker
(JIT=on)
0.39926886558533
  • 検証結果
    • macOS のデフォルト PHP 7.1.23 のローカル実行と比較しても 2〜3 倍速い。
    • JIT を有効にしない場合は PHP8 on Docker がローカル実行の PHP7.1.23 よりやや速いくらい。
    • v7.1.23 と v7.3.6 では、v7.3.6 の方がローカルより速い。
  • 検証環境
    • マシン: MacBook Pro, 2.7 GHz IntelCore, 13inch Early 2015
    • OS: macOS Mojave (OSX 10.14.5)
    • Docker: 19.03.2

Viewing all articles
Browse latest Browse all 521

Trending Articles