PHPのGeneratorは本当にメモリ消費量が減るのか実験
modern phpという書籍の勉強の過程で、PHPのGenerator機能の実験をしました。 https://www.amazon.co.jp/Modern-PHP-Features-Good-Practices/dp/1491905018www.amazon.co.jp
Generator機能を使うことで、 大量のデータを繰り返しで処理するときに、 使用メモリ量が少なくなるということなのですが、 実際のコードを見てみましょう。
たとえば、1番から100,000番までの番号を、 順番にエコーする以下のコードがあるとします。
<?php function makeNumbers() { $numbers = array(); for ( $index = 0; $index <= 100000; $index++ ) { $numbers[] = $index; } return $numbers; } $startTime = microtime(true); $startMemory = memory_get_usage(); foreach ( makeNumbers() as $number ) { echo $number; } $executionTime = microtime(true) - $startTime; $usedMemory = (memory_get_peak_usage() - $startMemory) / (1024 * 1024); echo "実行時間:{$executionTime}s"; echo "使用メモリ量:{$usedMemory}MB";
$numbersという配列に大量のデータが入るので、 メモリをたくさん使ってしまいますね。 Generatorを使えば、以下のように書けます。
<?php function makeNumbers() { for ( $index = 0; $index <= 100000; $index++ ) { yield $index; } } $startTime = microtime(true); $startMemory = memory_get_usage(); foreach ( makeNumbers() as $number ) { echo $number; } $executionTime = microtime(true) - $startTime; $usedMemory = (memory_get_peak_usage() - $startMemory) / (1024 * 1024); echo "実行時間:{$executionTime}s"; echo "使用メモリ量:{$usedMemory}MB";
yieldを使うことで、このように実装できます。 大量のデータが入っている配列の$numbersがなくなりましたね。
本当にメモリ消費量が減ったのでしょうか? 以下のような結果になりました。
種類 | メモリ消費量[MB] | 実行時間[s] |
---|---|---|
ジェネレータなし | 13.972MB | 0.286s |
ジェネレータあり | 0.004MB | 0.401s |
メモリ使用量が激減しました! 実行時間が増えているのが気になるところです。
当社ではGeneratorが使えるPHP7で開発をしています。