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に対して配列が入っているようなイメージだったので、その後の処理の違いでこんなに差が出るというのが感覚的には掴みづらいかも。
ただ、処理速度・使用メモリ共に顕著な差が出たので積極的に使っていきたいところ。
参考サイト
関連記事
-
-
PHPで日時のフォーマットをISO 8601型とDateTime型を相互に変換する方法
他社のAPI等のレスポンスで日時部分が「YYYY-MM-DDTHH:II:SSZ ...
-
-
PHPでダミー画像(プレースホルダー画像)を表示する「PHP-Dummy-Image-Generator」の利用方法
先日JavaScriptでダミー画像(プレースホルダー画像)を表示する「Hold ...
-
-
PHPで配列のキーの最大値を取得する方法
配列のキーに整数値が入っていて、その中から最大値を取得したいケースがあった。調べ ...
-
-
Codeigniter3で外部ファイル(CSS / JS)の読み込みと共通パーツ化する方法
CodeigniterでCSSやJSファイル等の外部ファイル読み込みたかった。ま ...
-
-
PHPで配列内から重複を削除する
やりたかった事はそのまま、配列内から重複を削除したかった。 ■参考サイト htt ...