運転に関しては、スピードがすべてではありません。しかし、ウェブでは速度がすべての違いを生みます。アプリケーションが高速であればあるほど、ユーザー エクスペリエンスは向上します。この記事は PHP ジェネレーターに関するものですが、なぜ速度について話しているのでしょうか?ジェネレータが速度とメモリ管理に大きな役割を果たしていることがすぐにわかります。
PHP ジェネレーターとは何ですか?
ジェネレーターは PHP 5.5 で追加され、メモリ内に配列を構築せずにデータを反復処理する簡単な方法を提供します。少し混乱していますか?次に、ジェネレーターの使用が良い方法であることを示す例を挙げます。
まず、この例全体で使用するgenerator.php ファイルを作成します。ファイルを作成した後、コードを追加します。
<?php function getRange ($max = 10) { $array = []; for ($i = 1; $i < $max; $i++) { $array[] = $i; } return $array; } foreach (getRange(15) as $range) { echo "Dataset {$range} <br>"; }
generator.php ファイルが作成されたディレクトリで組み込み PHP サーバーをすぐに起動できます:
php -S localhost:8000
ブラウザを使用して http://localhost:8000 を開く場合/generator.php、次のような結果が表示されるはずです。
#このコードは、あまり自明ではありません。コードを少し変更しましょう
<?php foreach (getRange(PHP_INT_MAX) as $range) { echo "Dataset {$range} <br>"; }
さて、上記のコードが生成できる最大値は PHP_INT_MAX (つまり、PHP が生成できる最大値) です。この変更後にブラウザを更新すると、次のようになります。今回は何かが違います。このジェネレータ スクリプトは警告メッセージをスローします。
#PHP がメモリ不足になるのは残念です。考えられる解決策としては、php.ini ファイルのmemory_limit の上限を増やすことが考えられます。しかし、公平を期すために言うと、このスクリプトは非効率的であり、メモリも消費します。必要なのは、効率的でメモリの消費量が少ないスクリプトです。
ジェネレーターの使用
上記と同じ関数を定義し、同じ値の PHP_INT_MAX で呼び出して、もう一度実行してみましょう。ただし、今回はジェネレーター関数を作成します。
<?php function getRange ($max = 10) { for ($i = 1; $i < $max; $i++) { yield $i; } } foreach (getRange(PHP_INT_MAX) as $range) { echo "Dataset {$range} <br>"; }
getRange 関数を解析します。今回は値のみをループして出力を生成します。 yield は関数から値を返すという点で戻り値と似ていますが、唯一の違いは、yield は必要な場合にのみ値を返し、データセット全体をメモリに保持しようとしないことです。
ブラウザにアクセスすると、ページにデータが表示されるはずです。適切な時間が与えられると、ブラウザーは最終的にデータを表示します。
注: ジェネレーターは関数内でのみ使用できます。
ジェネレーターを使用する理由
巨大なデータ セット (おそらくログ ファイル) を解析したい状況に遭遇することがあります。大規模なデータベースの結果セットなどに対して計算を実行することが可能です。このすべてのデータをメモリにロードする必要はありません。対応するメモリ状態を可能な限り保存する必要があります。データが大きい必要はありません。データがどれほど小さくても、ジェネレーターは効率的です。忘れないでください。私たちの目標は、メモリの使用量を減らしてできるだけ早くデータを処理することです。
キーと値のペアを返す
データがキーと値に基づいている場合、データの説得力が高まる場合があります。ジェネレーターを使用する場合、次のようなキーと値のペアを生成することがあります。
<?php function getRange ($max = 10) { for ($i = 1; $i < $max; $i++) { $value = $i * mt_rand(); yield $i => $value; } }
その後、このキーと値のペアを他の配列と同じように使用できます。
<?php foreach (getRange(PHP_INT_MAX) as $range => $value) { echo "Dataset {$range} has {$value} value<br>"; }
パラメーターをジェネレーターに渡す
ジェネレーターはパラメーターを受け取ることもできます。これは、ジェネレーターを使用すると、パラメーターをコマンドまたは他の関数としてジェネレーターに挿入できることを意味します。たとえば、ジェネレーターに値を送信して、ジェネレーターの実行を停止したり、出力を変更したりします。上記の getRange 関数を使用すると、これを実現できます。
<?php function getRange ($max = 10) { for ($i = 1; $i < $max; $i++) { $injected = yield $i; if ($injected === 'stop') return; } }
注入されたこの値を送信するには、次のようにします。
<?php $generator = getRange(PHP_INT_MAX); foreach ($generator as $range) { if ($range === 10000) { $generator->send('stop'); } echo "Dataset {$range} <br>"; }
注: ジェネレーター内で return を使用すると、ジェネレーターから飛び出します。
ジェネレーターを乱用しないでください
ただし、PHP_INT_MAX を使用するのは少しやりすぎです。しかし、私にとって、PHP_INT_MAX は 2147483647 で、これは次のとおりです。
20 億 4,714 万 83,647
#ジェネレーターはメモリ使用量を計算します。もっと効率的。しかし、乱用すると、記憶関連の問題を引き起こす可能性もあります。
概要
ジェネレーターは、無視できない大幅なパフォーマンスの向上をもたらします。ほとんどの場合、コードを実行するために高度な構成のサーバーは必要ありません。少しリファクタリングを行うだけで済みます。ジェネレーターは非常に便利なので、もっと使用する必要があります。
推奨チュートリアル: 「Laravel チュートリアル」「PHP チュートリアル」「PHP7」
以上がPHPのジェネレーターの詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。