Heim  >  Artikel  >  Backend-Entwicklung  >  Tools zur Leistungsoptimierung in PHP, die Sie möglicherweise übersehen: Generatorbezogene Inhalte

Tools zur Leistungsoptimierung in PHP, die Sie möglicherweise übersehen: Generatorbezogene Inhalte

jacklove
jackloveOriginal
2018-07-06 17:51:071308Durchsuche

Leistungsoptimierung ist ein wesentlicher Bestandteil unserer Entwicklung. Der folgende Artikel stellt Ihnen das Leistungsoptimierungstool in PHP vor, das Sie möglicherweise übersehen: Der Artikel stellt es anhand von Beispielcodes ausführlich vor In Not können Sie sich darauf beziehen, schauen wir uns unten um.

Vorwort

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 kann daran liegen, dass der Generator eine in PHP 5.5.0 eingeführte Funktion ist oder die Funktion des Generators nicht sehr offensichtlich ist. Allerdings ist die Generatorfunktion wirklich nützlich.

Unter welchen Umständen treten PHP-Leistungsprobleme auf?

1: Unangemessene Verwendung der PHP-Syntax.

2: Verwenden Sie die PHP-Sprache, um Dinge zu tun, in denen sie nicht gut ist.

3: Der über die PHP-Sprache verbundene Dienst ist nicht gut.

4: PHPs eigene Mängel (Dinge, die PHP selbst nicht kann).

5: Ein Problem, von dem wir noch nicht einmal wissen? (Um Lösungen zu erforschen, zu analysieren und zu finden und den Entwicklungsstand zu verbessern).

Vorteile

Wenn ich direkt über das Konzept spreche, werden Sie wahrscheinlich immer noch verwirrt sein, nachdem Sie es gehört haben, also lasst uns reden Zuerst geht es um die Vorteile, vielleicht kann es Ihr Interesse wecken. 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.

  • Konzepteinführung

Lassen Sie uns zunächst den Ballast des Generatorkonzepts beiseite legen und uns eine einfache PHP-Funktion ansehen:

function createRange($number){
 $data = [];
 for($i=0;$i<$number;$i++){
  $data[] = time();
 }
 return $data;
}

Dies ist eine sehr häufige PHP-Funktion, die wir häufig bei der Verarbeitung einiger Arrays verwenden. Auch hier ist der Code sehr einfach:

Wir erstellen eine Funktion.

Die Funktion enthält eine for-Schleife. Wir schleifen die aktuelle Zeit in $data.

  • Nachdem die for-Schleife ausgeführt wurde, geht $data zurück aus.

  • Es ist noch nicht vorbei, lasst uns weitermachen. Schreiben wir eine weitere Funktion und geben den Rückgabewert dieser Funktion in einer Schleife aus:

  • $result = createRange(10); // 这里调用上面我们创建的函数
    foreach($result as $value){
     sleep(1);//这里停顿1秒,我们后续有用
     echo $value.&#39;<br />&#39;;
    }

  • Schauen wir uns die laufenden Ergebnisse im Browser an:

Hier ist es perfekt, keinerlei Probleme. (Natürlich sieht man den Effekt von Schlaf nicht(1))

Denken Sie über eine Frage nach

Das ist uns aufgefallen beim Aufruf der Funktion createRange Der an $number übergebene Wert ist 10, eine sehr kleine Zahl. Angenommen, wir übergeben nun einen Wert von 10000000 (10 Millionen).

Dann muss in der Funktion createRange die for-Schleife 10 Millionen Mal ausgeführt werden. Und 10 Millionen Werte werden in $data abgelegt, und das $data-Array wird im Speicher abgelegt. Daher wird beim Aufrufen von Funktionen viel Speicher belegt.
Hier kann der Generator ins Spiel kommen.

Generator erstellen

Wir ändern den Code direkt, bitte beachten Sie:

function createRange($number){
 for($i=0;$i<$number;$i++){
  yield time();
 }
}

Sehen Sie sich diesen Code an, der dem gerade gezeigten sehr ähnlich ist. Wir haben das Array $data gelöscht und nichts zurückgegeben. Stattdessen haben wir das Schlüsselwort yield

Generator verwenden

Lassen Sie uns den zweiten Teil des Codes erneut ausführen:

$result = createRange(10); Hier rufen wir die Funktion auf, die wir oben erstellt haben foreach($result as $value){ sleep(1); echo $value.'df250b2156c434f3390392d09b1c9563';}


Wir haben auf wundersame Weise festgestellt, dass der Ausgabewert anders ist als beim ersten Mal ohne Verwendung des Generators. Die Werte (Zeitstempel) sind hier im Abstand von 1 Sekunde getrennt.

Das Ein-Sekunden-Intervall hier ist eigentlich das Ergebnis des Schlafs(1). Aber warum gibt es beim ersten Mal keine Lücke? Das liegt daran:

Wenn der Generator nicht verwendet wird: Das Ergebnis der for-Schleife innerhalb der createRange-Funktion wird schnell in $data abgelegt und sofort zurückgegeben. Daher ist die foreach-Schleife ein festes Array.

Bei Verwendung eines Generators: Der Wert von createRange wird nicht schnell auf einmal generiert, sondern basiert auf der foreach-Schleife. foreach-Schleifen durchlaufen einmal und for werden einmal ausgeführt.

  • An diesem Punkt sollten Sie eine Vorstellung vom Generator haben.

  • Umfassendes Verständnis von Generatoren

Code-Analyse

Lassen Sie uns jetzt den Code analysieren.

function createRange($number){
 for($i=0;$i<$number;$i++){
  yield time();
 }
}
$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
 sleep(1);
 echo $value.'
'; }


Lassen Sie uns den Codeausführungsprozess wiederherstellen.

  • 首先调用createRange函数,传入参数10,但是for值执行了一次然后停止了,并且告诉foreach第一次循环可以用的值。

  • foreach开始对$result循环,进来首先sleep(1),然后开始使用for给的一个值执行输出。

  • foreach准备第二次循环,开始第二次循环之前,它向for循环又请求了一次。

  • for循环于是又执行了一次,将生成的时间戳告诉foreach.

  • 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", &#39;rb&#39;);

 while (feof($handle)===false) {
  # code...
  yield fgets($handle);
 }

 fclose($handle);
}

foreach (readTxt() as $key => $value) {
 # code...
 echo $value.&#39;<br />&#39;;
}


通过上图的输出结果我们可以看出代码完全正常。

但是,背后的代码执行规则却一点儿也不一样。使用生成器读取文件,第一次读取了第一行,第二次读取了第二行,以此类推,每次被加载到内存中的文字只有一行,大大的减小了内存的使用。

这样,即使读取上G的文本也不用担心,完全可以像读取很小文件一样编写代码。

总结

您可能感兴趣的文章:

Laravel框架中composer自动加载的实现详解

PHP服务端环境搭建的图文教程

php实现希尔排序算法的方法讲解

Das obige ist der detaillierte Inhalt vonTools zur Leistungsoptimierung in PHP, die Sie möglicherweise übersehen: Generatorbezogene Inhalte. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn