1. g_kobayashi

    Posted

    g_kobayashi
Changes in title
+PHP5とPHP7の違いを肌で感じてみる(配列編)
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,114 @@
+仕事で久しぶりにPHPに触れることになりそうなのでウォーミングアップのつもりで今更ながらPHP7にチャレンジ。
+
+昔やってたPHP5との違いを配列の観点で比較して見た。
+一言で比較と言っても色々な観点があるし環境とか組み方も見なきゃだけど、まあウォーミングアップなので細かいことは置いておく。
+
+### 比較観点
+* 最大メモリ使用量
+* 処理速度
+
+### 比較環境
+* 端末:Macbook Air
+* CPU:Core i5 1.3GHz
+* メモリ:4GB 1600MHz DDR3
+* OS:Sierra 10.12.6
+
+### 検証対象
+* PHP5 … PHP 5.6.32 (cli) (built: Oct 27 2017 11:56:18)
+* PHP7 … PHP 7.0.26 (cli) (built: Dec 2 2017 13:12:39) ( NTS )
+
+## 検証
+
+### 検証方法
+土台としてこんな感じの検証コードを用意。
+配列をループで回して検証するシンプルなものだけど、シンプルじゃないと純粋な計測にならないのでこの程度で。
+良いブログがあったので参考にさせていただきました。
+(参考: https://qiita.com/h13/items/a75fba76f435212a2eb3)
+
+```
+<?php
+ $baseMem = memory_get_usage();
+ $startTime = microtime(true);
+
+ for ($i = 0; $i < 100; $i++) {
+ $data = range(1, 100000);
+ // {***ここに後述の検証パターン処理を差し込む***}
+
+ $data = null;
+ }
+
+ $maxMem = (memory_get_peak_usage() - $baseMem) / (1024 * 1024); // 最大メモリ使用量
+ $processTime = microtime(true) - $startTime; // 処理時間
+
+```
+
+### 検証パターン1. foreach
+
+```
+ $output = [];
+ foreach ($data as $value) {
+ $output[] = $value;
+ }
+```
+
+### 検証パターン2. foreachでメモリ節約
+
+```
+ foreach ($data as $key => $value) {
+ $output[] = $value;
+ unset($data[$key]);
+ }
+```
+
+### 検証パターン3. foreachで参照渡し
+
+```
+ foreach ($data as &$value) {
+ $output[] = $value;
+ }
+```
+
+### 検証パターン4. foreachで参照渡しでメモリ節約
+
+```
+ foreach ($data as &$value) {
+ $output[] = $value;
+ unset($value);
+ }
+```
+
+### 検証パターン5. while
+
+```
+ $output = [];
+ while (list(, $value) = each($data)) {
+ $output[] = $value;
+ }
+```
+
+### 検証パターン6. whileのメモリ節約
+
+```
+ while (list($key, $value) = each($data)) {
+ $output[] = $value;
+ unset($data[$key]);
+ }
+```
+
+## 検証結果
+| 検証番号 | [PHP5] 最大メモリ(MB) | [PHP5] 時間(秒) | [PHP7] 最大メモリ(MB) | [PHP7] 時間(秒) | [PHP7効果] 最大メモリ(MB) | [PHP7効果] 時間(秒) |
+|:---:|---:|---:|---:|---:|:---:|:---:|
+| 1 | 27.96 | 4.68 | 8.008 | 0.80 | 約 1/3 | 約 1/6 |
+| 2 | 28.20 | 6.08 | 12.012 | 1.37 | 約 1/2 | 約 1/4 |
+| 3 | 27.95 | 4.90 | 10.297 | 0.98 | 約 1/3 | 約 1/5 |
+| 4 | 27.95 | 5.63 | 10.297 | 1.00 | 約 1/3 | 約 1/6 |
+| 5 | 28.20 | 12.9 | 8.008 | 3.08 | 約 1/4 | 約 1/4 |
+| 6 | 28.06 | 7.22 | 8.008 | 3.56 | 約 1/4 | 約 1/2 |
+
+まあ、言わずもがなですが圧倒的な差が出ましたね。
+
+foreachが速くなった理由は、PHP5からPHP7ではデータ構造・配列構造が改善されたのとBucket構造体がメモリの連続確保に変わったからと言うのが大きいのかなと思った。そもそもL1キャッシュを利用できるとかコンパイル時にASTを噛ませるようになったとかも影響してるのだろうけど、その辺の実証はまたいずれ。
+
+## おまけ
+今回とは少しズレるけどPHP7ではイテレートの変数に対して内部ポインタを使わなくなってるので、PHP5でcurrent()とかreset()とか使ってる状態でPHP7にすると結果が変わってしまう。
+要注意のメモ。