目標
PHP 5.6とPHP 7.0のパフォーマンスの違いを検証するため、他の条件は同じにした上で、PHPのバージョンだけ差し替えて実行する環境を用意します。
方針
VirtualBox + Vagrantで、CentOS 6の環境を作って、そこで検証します。
CentOSのyum
コマンドの--enablerepo
オプションを使うことで、PHPバージョンの切換を行います。
構築手順
VMのセットアップ
まず、VirtualBoxとVagrantの最新版をインストールしてください。
VirtualBoxとVagrantをインストールしたら、適当な作業ディレクトリを作成して、以下のコマンドを実行します。
$ vagrant init puphpet/centos65-x6
これにより、現在のディレクトリにVagrantfile
という名前のファイルが作成されます。Vagrantfile
を開いて、以下の行のコメントアウトを解除(行頭の#
を削除)してください。
# config.vm.network "forwarded_port", guest: 80, host: 8080
これによって、VM上の80番ポート(HTTP)に、ホストマシンの8080番ポートからアクセスできるようになります。
次に、以下のコマンドでVMを起動します。
$ vagrant up
しばらく待つと、VMが起動するので、以下のコマンドでログインします。
$ vagrant ssh
CentOSセットアップ
はじめにパッケージを最新版に更新しておきましょう。
$ sudo yum update
WebサーバーはApacheを入れます。インストールできたらservice
コマンドで起動します。
$ sudo yum install httpd
$ sudo service httpd start
次に、PHP 5.6、PHP 7.0をインストールするため、Remiリポジトリを追加します。
$ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
まずはPHP 5.6を入れます。php-xmlは後述するSymfonyが使用します。
$ sudo yum install --enablerepo=php56 php php-common php-opcache php-xml
$ sudo service httpd restart
ここまででPHPのインストールが終わりました。次に、ベンチマーク対象となるスクリプトを作成します。ここでは、計量なベンチマークとして「hello」を表示するだけのスクリプトを、重量級のベンチマークについては、Symfonyフレームワークを使用します。
まずは、Apacheの公開ディレクトリの権限を変更しておきます。
$ sudo chmod -R 777 /var/www/html
なお、/var/www/html
を777に設定するのは、作業を簡単に進めるためです。本番環境で推奨される設定ではありません。
次に、メモリ使用量を記録するファイルを作成し、apacheユーザが書き込みできるよう権限を設定します。
$ touch /tmp/memory_usage.txt
$ chmod 777 /tmp/memory_usage.txt
軽量なスクリプトについては、/var/www/html/hello.php
というファイルを、以下の内容で作成します。
<?php
echo 'hello';
error_log(memory_get_peak_usage() . PHP_EOL, 3, '/tmp/memory_usage.txt');
'hello'と表示した後に、メモリ使用量のピーク値をログファイルに出力して終了しています。
このスクリプトには、http://127.0.0.1:8080/hello.php
というURLでアクセスできます。
Symfonyは以下の手順でインストールします。
$ sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
$ sudo chmod a+x /usr/local/bin/symfony
$ cd /var/www/html
$ symfony new bench
フロントコントローラー(web/app.php
)の末尾に、以下の行を追加します。先ほどのスクリプトと同様、メモリ使用量をログファイルに書き出します。
error_log(memory_get_peak_usage() . PHP_EOL, 3, '/tmp/memory_usage.txt');
http://127.0.0.1:8080/bench/web
というURLにアクセスすると、Symfonyのスタートページが表示されます。
ベンチマーク
ベンチマークは、ホストマシン(Mac)でab
コマンドを使用して行います。最初の1回は、キャッシュが効かないため低速になります。2回め以降の計測値はほぼ安定します。
ab
コマンドを実行すると、以下のような結果が表示されます。
$ ab -k -c4 -n 100 http://127.0.0.1:8080/hello.php
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient).....done
Server Software: Apache/2.2.15
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /hello.php
Document Length: 5 bytes
Concurrency Level: 4
Time taken for tests: 0.129 seconds
Complete requests: 100
Failed requests: 0
Keep-Alive requests: 0
Total transferred: 19700 bytes
HTML transferred: 500 bytes
Requests per second: 773.11 [#/sec] (mean)
Time per request: 5.174 [ms] (mean)
Time per request: 1.293 [ms] (mean, across all concurrent requests)
Transfer rate: 148.73 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.6 0 4
Processing: 1 5 4.5 3 31
Waiting: 1 3 3.4 3 31
Total: 1 5 4.6 3 31
Percentage of the requests served within a certain time (ms)
50% 3
66% 4
75% 6
80% 8
90% 11
95% 15
98% 18
99% 31
100% 31 (longest request)
注目すべきは、「Requests per second」と、「Time per request」です。
Request per secondは、1秒間あたりに処理可能なリクエスト数、Time per requestはリクエストを送ってからレスポンスが返ってくるまでの時間(レイテンシ)のことです。
/tmp/memory_usage.txt
にも、以下のような数字が書き込まれているはずです。
384384
これは、メモリ使用量で、単位はバイトです。↑の場合、約375KBのメモリを使用しています。
以下が、私の手元の環境で取得した、PHP 5.6版のベンチマークです。
Requests per second | Time per request | Memory usage | |
---|---|---|---|
hello | 806.35 [#/sec] | 4.961 [ms] | 216184 [byte] |
Symfony | 68.26 [#/sec] | 58.600 [ms] | 2595688 [byte] |
PHP 7.0インストール
PHP 5.6の計測ができたので、5.6をアンインストールして7.0をインストールします。
$ sudo yum remove php php-common php-opcache php-xml
$ sudo yum install --enablerepo=remi-php70 php php-common php-opcache php-xml
$ sudo service httpd restart
以下が、私の手元の環境で取得した、PHP 7.0版のベンチマークです。
Requests per second | Time per request | Memory usage | |
---|---|---|---|
hello | 756.38 [#/sec] | 5.288[ms] | 348056 [byte] |
Symfony | 102.10 [#/sec] | 39.176 [ms] | 1857400 [byte] |
考察
PHP 5.6と7.0のそれぞれを比較してみると、興味深いことがわかります。
- 軽量なスクリプトでは、PHP 7.0でも速度はほとんど変わらない(というか、傾向として5.6よりも遅くなる)
- 本格的なアプリケーションでは、PHP 7.0の方が高速で、メモリ使用量も少ない
【hello】
Requests per second | Time per request | Memory usage | |
---|---|---|---|
5.6 | 806.35 [#/sec] | 4.961 [ms] | 216184 [byte] |
7.0 | 768.67 [#/sec] | 5.288 [ms] | 348056 [byte] |
【Symfony】
Requests per second | Time per request | Memory usage | |
---|---|---|---|
5.6 | 68.26 [#/sec] | 58.600 [ms] | 2595688 [byte] |
7.0 | 102.10 [#/sec] | 39.176 [ms] | 1857400 [byte] |
速度が速いという情報はよく見ますが、メモリ使用量はどうなの? と思ったのでベンチマーク取ってみました。