1. g_kobayashi

    No comment

    g_kobayashi
Changes in body
Source | HTML | Preview
@@ -1,117 +1,118 @@
仕事で久しぶりにPHPに触れることになりそうなのでウォーミングアップのつもりで今更ながらPHP7にチャレンジ。(PHP8の足音が。。。)
昔やってた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 )
## 検証
+PHP5からPHP7では色々と変わったけど、データ構造・配列構造が改善されたのとBucket構造体が変わったとの話があったので、今回はその観点で検証する。
### 検証方法
土台としてこんな感じの検証コードを用意。
配列をループで回して検証するシンプルなものだけど、シンプルじゃないと純粋な計測にならないのでこの程度で。
良いブログがあったので参考にさせていただきました。
(参考: https://qiita.com/h13/items/a75fba76f435212a2eb3)
```php:base.php
<?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
```php:foreach.php
$output = [];
foreach ($data as $value) {
$output[] = $value;
}
```
### 検証パターン2. foreachでメモリ節約
```php:foreach-eco.php
foreach ($data as $key => $value) {
$output[] = $value;
unset($data[$key]);
}
```
### 検証パターン3. foreachで参照渡し
```php:foreach-ref.php
foreach ($data as &$value) {
$output[] = $value;
}
```
### 検証パターン4. foreachで参照渡しでメモリ節約
```php:foreach-ref-eco.php
foreach ($data as &$value) {
$output[] = $value;
unset($value);
}
```
### 検証パターン5. while
```php:while.php
$output = [];
while (list(, $value) = each($data)) {
$output[] = $value;
}
```
### 検証パターン6. whileのメモリ節約
```php:while-eco.php
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とPHP8の検証の方がいいかもだけど)
+PHP7が速くなった理由は、そもそもL1キャッシュを利用できるとかコンパイル時にASTを噛ませるようになったとかも影響してるのだろうけど、その辺の実証はまたいずれ。(その頃はPHP7とPHP8の検証の方がいいかもだけど)
## おまけ
今回とは少しズレるけどPHP7ではイテレートの変数に対して内部ポインタを使わなくなってるので、PHP5でcurrent()とかreset()とか使ってる状態でPHP7にすると結果が変わってしまう。
要注意のメモ。
## おまけのおまけ
Merry X'mas!!