PHPにて配列の出力時にジェネレータを利用してメモリを節約する方法
PHPにて大量のデータが格納された配列をforeach等でループ処理するような場合、memory_limitが気になることがある。特にシステムのリリース当初は大丈夫でも、その後データが増えていくような場合だとさらに気になる。そのような場合、ジェネレータを使うとメモリを節約できるらしい。以下に利用方法をメモ。
想定
過去に取得した全国の市区町村データが入っているMySQLから10,000件取得してID(通し番号)をvar_dump()で出力する。
その際の処理にかかった時間とメモリ使用量を測定する。
利用方法
ソースコード
<?php #通常版 $sql = ' SELECT * FROM ad_address LIMIT 10000 '; $row = $mysqli->query($sql); while( $rs = $row->fetch_array(MYSQLI_ASSOC) ){ var_dump($rs['id']); } #ジェネレータ版 function getAddress(){ $sql = ' SELECT * FROM ad_address LIMIT 10000 '; $row = $mysqli->query($sql); while( $rs = $row->fetch_array(MYSQLI_ASSOC) ){ yield $rs['id']; } } foreach( getAddress() as $val ){ var_dump($val); }
測定結果
以下の通り顕著な差が出た。
- 通常版 → 処理時間0.099609693秒 / 使用メモリ2.17MB
- ジェネレータ版 → 処理時間0.013392766秒 / 使用メモリ418.55KB
リファレンス
https://www.php.net/manual/ja/language.generators.overview.php
所感
「$row = $mysqli->query($sql);」の時点で$rowに対して配列が入っているようなイメージだったので、その後の処理の違いでこんなに差が出るというのが感覚的には掴みづらいかも。
ただ、処理速度・使用メモリ共に顕著な差が出たので積極的に使っていきたいところ。
参考サイト
関連記事
-
-
PHP5.4系でAPCが上手く動かなかったので5.5にアップデート&Zend OPcache導入
PHP5.3系から5.4系にアップデートしてから、WordPressがちょっと重 ...
-
-
PHPで多次元連想配列のキーを指定してソート
やりたかった事は、 ・多次元配列があってcodeというキーでソートしたい という ...
-
-
レンタルサーバでPHPのsystem関数やexec関数が使用できずにエラーが出力される
レンタルサーバ上でPHPのsystem関数を実行しようとすると「Fatal er ...
-
-
CodeIgniter4で特定のページにアクセスがあった際に301リダイレクトさせる方法
CodeIgniter4で特定のページにアクセスがあった際に301リダイレクトさ ...
-
-
PHPでスマホ(iPhone / Android)に画像をダウンロードさせる方法とダウンロード後の保存場所について
PHPで作ったシステムにスマホ(iPhone / Android)でアクセスし何 ...