PHPのパフォーマンス比較（5.3〜7.0）

PHP5.3から7までのパフォーマンスを比較してみました。

# 環境

[こちら](http://bashalog.c-brains.jp/15/06/08-100000.php)の記事を参考にさせていただき、Vagrant でテスト環境を用意します。

```console:各PHPのバージョン
vagrant@php7dev:/var/www/default$ php53 -v
PHP 5.3.30-dev (cli) (built: Jan 29 2015 17:42:37) 
vagrant@php7dev:/var/www/default$ php54 -v
PHP 5.4.46-dev (cli) (built: Oct 22 2015 16:34:09) 
vagrant@php7dev:/var/www/default$ php55 -v
PHP 5.5.31-dev (cli) (built: Oct 22 2015 16:24:08) 
vagrant@php7dev:/var/www/default$ php56 -v
PHP 5.6.16-dev (cli) (built: Oct 22 2015 16:13:30) 
vagrant@php7dev:/var/www/default$ php7 -v
PHP 7.0.0-dev (cli) (built: Oct 22 2015 19:38:21) ( NTS )
```

マシンは Macbook Pro 13インチです。

 <img width="301" alt="スクリーンショット 2015-12-23 17.06.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/20940/a2444064-7f5e-f680-a87e-6d352a7974a1.png">



# 比較1

フィボナッチ数を計算して、処理時間とメモリ使用量を見てみます。

```php:fibonacci.php
<?php
function fibonacci($n)
{
    if ($n < 2) {
        return $n;
    }
    return fibonacci($n - 2) + fibonacci($n - 1);
}

$time_start = microtime(true);
$temp = fibonacci(38);
$time_end = microtime(true);

echo 'time : ' . ($time_end - $time_start) . ' sec     ' .
     'mem : ' . (memory_get_usage() / 1024 / 1024) . ' MB' . PHP_EOL;
```

実行は下記のようにコマンドラインから5回ずつ行いました。
`php53` の部分は各バージョンに置き換えてください。

```console:5回実行する
$ for i in {0..4}; do php53 fibonacci.php; done;
```

**結果**

```console:
$ for i in {0..4}; do php53 fibonacci.php; done;
time : 8.8745021820068 sec     mem  : 0.59640502929688 MB
time : 8.340313911438 sec      mem  : 0.59640502929688 MB
time : 9.9600381851196 sec     mem  : 0.59640502929688 MB
time : 9.4626259803772 sec     mem  : 0.59640502929688 MB
time : 9.5003471374512 sec     mem  : 0.59640502929688 MB

$ for i in {0..4}; do php54 fibonacci.php; done;
time : 7.6157579421997 sec     mem  : 0.21370697021484 MB
time : 8.6955020427704 sec     mem  : 0.21370697021484 MB
time : 6.9724881649017 sec     mem  : 0.21370697021484 MB
time : 6.9245629310608 sec     mem  : 0.21370697021484 MB
time : 7.2523899078369 sec     mem  : 0.21370697021484 MB

$ for i in {0..4}; do php55 fibonacci.php; done;
time : 6.5647640228271 sec     mem  : 0.21321105957031 MB
time : 6.6234068870544 sec     mem  : 0.21321105957031 MB
time : 6.6727700233459 sec     mem  : 0.21321105957031 MB
time : 6.7943079471588 sec     mem  : 0.21321105957031 MB
time : 7.0112040042877 sec     mem  : 0.21321105957031 MB

$ for i in {0..4}; do php56 fibonacci.php; done;
time : 7.3396279811859 sec     mem  : 0.21321868896484 MB
time : 8.8106920719147 sec     mem  : 0.21321868896484 MB
time : 7.6103270053864 sec     mem  : 0.21321868896484 MB
time : 6.5883009433746 sec     mem  : 0.21321868896484 MB
time : 7.0513398647308 sec     mem  : 0.21321868896484 MB

$ for i in {0..4}; do php7 fibonacci.php; done;
time : 2.2508449554443 sec     mem  : 0.3321533203125 MB
time : 2.3575670719147 sec     mem  : 0.3311767578125 MB
time : 2.1691491603851 sec     mem  : 0.3311767578125 MB
time : 2.0446121692657 sec     mem  : 0.3311767578125 MB
time : 2.1461308002472 sec     mem  : 0.3311767578125 MB
```

**平均**

|バージョン|実行時間（秒）|メモリ（MB）|
|-----|-----:|-----:|
|5.3|9.227565479|0.596405029|
|5.4|7.492140198|0.213706970|
|5.5|6.733290577|0.213211060|
|5.6|7.480057573|0.213218689|
|7.0|2.193660831|0.331372070|

PHP7の実行時間が突出して短くなっていますね。
ただPHP7でメモリ使用量が削減されたはずですが、この処理では過去のバージョンと比較して多くなっていますね。関数を呼んでいるだけなので、新たにメモリが確保されないのか。


# 比較2

メモリの使用量について見てみたいので、単純に連想配列を作成する際の結果を比較してみます。

```array_test.php
<?php
$time_start = microtime(true);
$i = range(0, 1000000);
$new = array();
foreach ($i as $i) {
    $k = 'key' . $i;
    $new[$k] = $i;
}
$time_end = microtime(true);

echo 'time : ' . ($time_end - $time_start) . ' sec     ' .
     'mem : ' . (memory_get_usage() / 1024 / 1024) . ' MB' . PHP_EOL;
```

**結果**

```console:
$ for i in {0..4}; do php53 array_test.php; done;
time : 0.38774800300598 sec     mem : 152.79147338867 MB
time : 0.40927910804749 sec     mem : 152.79147338867 MB
time : 0.36143684387207 sec     mem : 152.79147338867 MB
time : 0.33564782142639 sec     mem : 152.79147338867 MB
time : 0.38382601737976 sec     mem : 152.79147338867 MB

$ for i in {0..4}; do php54 array_test.php; done;
time : 0.3762321472168 sec      mem : 153.09534454346 MB
time : 0.39958381652832 sec     mem : 153.09535980225 MB
time : 0.38534998893738 sec     mem : 153.09535980225 MB
time : 0.39422106742859 sec     mem : 153.09535980225 MB
time : 0.35958099365234 sec     mem : 153.09535980225 MB

$ for i in {0..4}; do php55 array_test.php; done;
time : 0.34950494766235 sec     mem : 153.09490966797 MB
time : 0.31725001335144 sec     mem : 153.09490966797 MB
time : 0.36130309104919 sec     mem : 153.09490966797 MB
time : 0.3703031539917 sec      mem : 153.09488677979 MB
time : 0.36027407646179 sec     mem : 153.09490966797 MB

$ for i in {0..4}; do php56 array_test.php; done;
time : 0.36537909507751 sec     mem : 153.09491729736 MB
time : 0.35702300071716 sec     mem : 153.09491729736 MB
time : 0.35819411277771 sec     mem : 153.09491729736 MB
time : 0.30669116973877 sec     mem : 153.09491729736 MB
time : 0.33337306976318 sec     mem : 153.09491729736 MB

$ for i in {0..4}; do php7 array_test.php; done;
time : 0.13665795326233 sec     mem : 74.404922485352 MB
time : 0.10781693458557 sec     mem : 74.404922485352 MB
time : 0.13959193229675 sec     mem : 74.404922485352 MB
time : 0.14009881019592 sec     mem : 74.404922485352 MB
time : 0.14135408401489 sec     mem : 74.404922485352 MB
```

**平均**

|バージョン|実行時間（秒）|メモリ（MB）|
|-----|-----:|-----:|
|5.3|0.375587559|152.7914734|
|5.4|0.382993603|153.0953568|
|5.5|0.351727057|153.0949051|
|5.6|0.344132090|153.0949173|
|7.0|0.133103943|74.40492249|

実行時間、メモリ使用量ともにPHP7が大きく削減されていますね :+1: 


# 比較3

最後にWebサーバ経由でアクセスしてみます。
この環境は `nginx 1.8.0 ＋ PHP-FPM` で動作しています。

またPHP-FPMの切り替えは、コマンドラインから以下のようにして行うことができます。

```console:PHP5.5からPHP7に切り替え
$ sudo service php55-fpm stop;
$ sudo service php-fpm start
```

ドキュメントルートに `Fuelphp` をデフォルト状態で置いて、確認してみます。
100クライアントから10回ずつアクセスが来た想定で、以下のようにテストします。

```console:ローカルから実行
$ ab -n 1000 -c 100 http://192.168.33.10/public/
```

**結果（抜粋）**

```console:
# php 5.3
Concurrency Level:      100
Time taken for tests:   26.637 seconds
Complete requests:      1000
Failed requests:        85
   (Connect: 0, Receive: 0, Length: 85, Exceptions: 0)
Total transferred:      28978908 bytes
HTML transferred:       28812908 bytes
Requests per second:    37.54 [#/sec] (mean)
Time per request:       2663.728 [ms] (mean)
Time per request:       26.637 [ms] (mean, across all concurrent requests)
Transfer rate:          1062.41 [Kbytes/sec] received

# php 5.4
Concurrency Level:      100
Time taken for tests:   26.427 seconds
Complete requests:      1000
Failed requests:        99
   (Connect: 0, Receive: 0, Length: 99, Exceptions: 0)
Total transferred:      28978890 bytes
HTML transferred:       28812890 bytes
Requests per second:    37.84 [#/sec] (mean)
Time per request:       2642.657 [ms] (mean)
Time per request:       26.427 [ms] (mean, across all concurrent requests)
Transfer rate:          1070.88 [Kbytes/sec] received

# php 5.5
Concurrency Level:      100
Time taken for tests:   25.935 seconds
Complete requests:      1000
Failed requests:        106
   (Connect: 0, Receive: 0, Length: 106, Exceptions: 0)
Total transferred:      28978875 bytes
HTML transferred:       28812875 bytes
Requests per second:    38.56 [#/sec] (mean)
Time per request:       2593.493 [ms] (mean)
Time per request:       25.935 [ms] (mean, across all concurrent requests)
Transfer rate:          1091.18 [Kbytes/sec] received

# php 5.6
Concurrency Level:      100
Time taken for tests:   25.884 seconds
Complete requests:      1000
Failed requests:        85
   (Connect: 0, Receive: 0, Length: 85, Exceptions: 0)
Total transferred:      28978904 bytes
HTML transferred:       28812904 bytes
Requests per second:    38.63 [#/sec] (mean)
Time per request:       2588.385 [ms] (mean)
Time per request:       25.884 [ms] (mean, across all concurrent requests)
Transfer rate:          1093.33 [Kbytes/sec] received

# php 7.0
Concurrency Level:      100
Time taken for tests:   26.317 seconds
Complete requests:      1000
Failed requests:        100
   (Connect: 0, Receive: 0, Length: 100, Exceptions: 0)
Total transferred:      29262892 bytes
HTML transferred:       29097892 bytes
Requests per second:    38.00 [#/sec] (mean)
Time per request:       2631.733 [ms] (mean)
Time per request:       26.317 [ms] (mean, across all concurrent requests)
Transfer rate:          1085.86 [Kbytes/sec] received
```

10%ぐらいFailしていますね、、、意味のデータかもしれませんが、一応載せておきます。

**比較**

|バージョン|Requests per second|Time per request (ms)|
|-----|-----:|-----:|
|5.3|37.54|26.637|
|5.4|37.84|26.427|
|5.5|38.56|25.935|
|5.6|38.63|25.884|
|7.0|38.00|26.317|

うーん、[こんなの](http://talks.php.net/fluent15#/wpbench)を期待していたのですが、、、テスト方法を見なおしてまたやってみます。


# 参考にしたサイト

【PHP】 PHP5.4系とPHP7系のパフォーマンスを比較してみた
http://deadcode.hatenablog.jp/entry/2015/11/04/171450

PHP7を試してみた
http://befool.co.jp/blog/chainzhang/first-taste-of-php7/