Heim > Artikel > Backend-Entwicklung > Leistungsoptimierungstool in PHP: Detaillierte Erklärung des PHP-Generators
Dieser Artikel stellt Ihnen eine detaillierte Erklärung des Leistungsoptimierungstools in PHP vor: Der PHP-Generator hat einen gewissen Referenzwert. Ich hoffe, er wird für Sie hilfreich sein.
Wenn Sie in Python oder anderen Sprachen arbeiten, sollten Sie mit Generatoren vertraut sein. Viele PHP-Entwickler kennen die Generatorfunktion jedoch möglicherweise nicht. Dies liegt möglicherweise daran, dass der Generator eine in PHP 5.5.0 eingeführte Funktion ist, oder dass die Funktion des Generators nicht sehr offensichtlich ist. Allerdings ist die Generatorfunktion wirklich nützlich.
Vorteile
Wenn ich direkt über das Konzept spreche, werden Sie vermutlich immer noch verwirrt sein, nachdem Sie es sich angehört haben. Sprechen wir also zuerst über die Vorteile. Vielleicht gelingt es ja wecken Sie Ihr Interesse. Was sind also die Vorteile von Generatoren? Läufe Sparen Sie viel Speicher
Eher geeignet für die Berechnung großer Datenmengen
Wie werden diese magischen Funktionen erreicht? Lassen Sie uns zunächst ein Beispiel geben.
function createRange($number){ $data = []; for($i=0;$i<p>Das ist Eine sehr verbreitete PHP-Funktion, die wir häufig bei der Verarbeitung einiger Arrays verwenden. Auch hier ist der Code sehr einfach: </p><p><strong></strong>Wir erstellen eine Funktion. Die </p><p></p><p>-Funktion enthält eine </p>-Schleife. Wir schleifen die aktuelle Zeit in die <ol class=" list-paddingleft-2"> <li><p></p></li> <li>-Schleifenausführung. Wenn Sie fertig sind, zurück <p>. <code>for</code><code>$data</code></p> </li>Es ist noch nicht vorbei, lasst uns weitermachen. Schreiben wir eine weitere Funktion und geben den Rückgabewert dieser Funktion in einer Schleife aus: <li> <pre class="brush:php;toolbar:false">$result = createRange(10); // 这里调用上面我们创建的函数 foreach($result as $value){ sleep(1);//这里停顿1秒,我们后续有用 echo $value.'<br>'; }
Schauen wir uns die laufenden Ergebnisse im Browser an: for
$data
nicht)
Denken Sie über eine Frage nach
Uns ist aufgefallen, dass beim Aufruf der Funktion der Pass bis sleep(1)
Der Wert ist 10, eine sehr kleine Zahl. Angenommen, Sie übergeben nun einen Wert
Dann muss in der Funktion die
-Schleife zehntausend Mal ausgeführt werden. Und in createRange
sind $number
zehntausend Werte abgelegt, und das Array 10000000
wird im Speicher abgelegt. Daher wird beim Aufrufen von Funktionen viel Speicher belegt.
Hier kann der Generator ins Spiel kommen. createRange
for
1000
Generator erstellen1000
$data
$data
Wir ändern den Code direkt, bitte achten Sie darauf:
function createRange($number){ for($i=0;$i<p>Sehen Sie sich diesen Code an, der dem gerade sehr ähnlich ist, wir lösche das Array </p> und habe nichts zurückgegeben, sondern ein Schlüsselwort <p><strong></strong></p> verwendet, bevor wir <p> den Generator </p><p><code>$data</code> verwendet haben. Wir führen das zweite Stück aus des Codes noch einmal: <code>time()</code></p><pre class="brush:php;toolbar:false">$result = createRange(10); // 这里调用上面我们创建的函数 foreach($result as $value){ sleep(1); echo $value.'<br>'; }
yield
Wir haben auf wundersame Weise festgestellt, dass der Ausgabewert anders ist als beim ersten Mal, ohne den Generator zu verwenden. Die Werte (Zeitstempel) sind hier im Abstand von 1 Sekunde getrennt. Die Lücke von einer Sekunde hier ist eigentlich die Folge von
. Aber warum gibt es beim ersten Mal keine Lücke? Das liegt daran:
Wenn kein Generator verwendet wird: Das Ergebnis der-Schleife innerhalb der
-Funktion wird schnell in abgelegt und sofort zurückgegeben. Daher durchläuft sleep(1)
ein festes Array.
Bei Verwendung von Generatoren: Der Wert von createRange
wird nicht schnell auf einmal generiert, sondern basiert auf der for
-Schleife. $data
Einmal Schleife und foreach
einmal ausführen.
An diesem Punkt sollten Sie eine Vorstellung vom Generator haben. createRange
foreach
foreach
Umfassendes Verständnis des Generatorsfor
Lassen Sie uns jetzt den Code analysieren. function createRange($number){
for($i=0;$i';
}
Lassen Sie uns den Codeausführungsprozess wiederherstellen.
ruft zuerst die Funktion
auf und übergibt den Parameter, aber der Wert
wird einmal ausgeführt und stoppt dann und teiltmit, dass die erste Schleife ausgeführt wird nutzbarer Wert.
createRange
startet die Schleife auf 10
, kommt zuerst for
herein und beginnt dann, einen durch foreach
gegebenen Wert zu verwenden, um die Ausgabe durchzuführen.
foreach
bereitet sich auf die zweite Schleife vor, bevor die zweite Schleife erneut angefordert wird. Anschließend wird die $result
sleep(1)
for
weitergegeben
foreach
拿到第二个值,并且输出。由于foreach
中sleep(1)
,所以,for
循环延迟了1秒生成当前时间
所以,整个代码执行中,始终只有一个记录值参与循环,内存中也只有一条信息。
无论开始传入的$number
有多大,由于并不会立即生成所有结果集,所以内存始终是一条循环的值。
概念理解
到这里,你应该已经大概理解什么是生成器了。下面我们来说下生成器原理。
首先明确一个概念:生成器yield关键字不是返回值,他的专业术语叫产出值,只是生成一个值
那么代码中foreach
循环的是什么?其实是PHP在使用生成器的时候,会返回一个Generator
类的对象。foreach
可以对该对象进行迭代,每一次迭代,PHP会通过Generator
实例计算出下一次需要迭代的值。这样foreach
就知道下一次需要迭代的值了。
而且,在运行中for
循环执行后,会立即停止。等待foreach
下次循环时候再次和for
索要下次的值的时候,for
循环才会再执行一次,然后立即再次停止。直到不满足条件不执行结束。
实际开发应用
很多PHP开发者不了解生成器,其实主要是不了解应用领域。那么,生成器在实际开发中有哪些应用?
读取超大文件
PHP开发很多时候都要读取大文件,比如csv文件、text文件,或者一些日志文件。这些文件如果很大,比如5个G。这时,直接一次性把所有的内容读取到内存中计算不太现实。
这里生成器就可以派上用场啦。简单看个例子:读取text文件
我们创建一个text文本文档,并在其中输入几行文字,示范读取。
<?php header("content-type:text/html;charset=utf-8"); function readTxt() { # code... $handle = fopen("./test.txt", 'rb'); while (feof($handle)===false) { # code... yield fgets($handle); } fclose($handle); } foreach (readTxt() as $key => $value) { # code... echo $value.'<br>'; }
通过上图的输出结果我们可以看出代码完全正常。
但是,背后的代码执行规则却一点儿也不一样。使用生成器读取文件,第一次读取了第一行,第二次读取了第二行,以此类推,每次被加载到内存中的文字只有一行,大大的减小了内存的使用。
这样,即使读取上G的文本也不用担心,完全可以像读取很小文件一样编写代码。
相关文章推荐:
PHP7中生成器的新特性:生成器委托( yield-from )&返回值(return-value)
Das obige ist der detaillierte Inhalt vonLeistungsoptimierungstool in PHP: Detaillierte Erklärung des PHP-Generators. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!