MatchinGoodエンジニアブログ

MatchinGood株式会社のエンジニアリング事情を共有します

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で開発をしています。 最近、PHP7で以下のサイトをリリースしました。

派遣会社と転職エージェントの日本最大級の評判・クチコミサイト【キャリレポ】

モダンな環境でPHP技術を磨きたい方は是非当社にご応募ください!

採用情報 | 人材紹介・人材派遣のシステム・パッケージソフトならマッチングッド