Pufferung von Ausgaben

Um jedes Quentchen Leistung aus einer Anwendung zu holen, versuchen Entwickler großer Seiten die Ausgaben zu puffern. Ds bedeutet, dass nicht alle Ausgabe-Befehle dort ausgeführt werden, wo sie stehen, sondern erst, wenn der Puffer geleert wird. Man sammelt sozusagen alle Ausgaben und gibt sie dann in einem Rutsch aus.

Das System der Pufferung kann man auf (mindestens) zwei Arten lösen: Entweder man schreibt alle Ausgaben in einen String (konkateniert die neue Ausgabe mit der bisher bereits bis zu dieser Zeile vorliegenden) oder man verwendet den internen Puffer von PHP. In Code sehen die beiden Wege so aus:

//Initialisieren des Ausgabestings
$str = "";
 
//Konkatenation neuer Ausgaben
$str .= "Dies ist eine Ausgabe";
$str .= " und sie enthält keinen großen Mehrwert.";
$str .= " Trotzdem zeigt sie, wie die Pufferung funktioniert.";
 
//eigentliche Ausgabe auf dem Bildschirm
echo $str;

Oder die Variante mit dem PHP-Puffer, der wesentlich eleganter auf bereits vorhandene Scripte anwendbar ist, die ohne Pufferung geschrieben wurden und nun aber doch damit ausgestattet werden sollen.

//PHP anweisen, dass alle Ausgaben in den internen Puffer geschrieben werden sollen
ob_start();
 
//Ausgaben in Puffer schreiben
echo "Dies ist eine Ausgabe";
echo " und sie enthält keinen großen Mehrwert.";
echo " Trotzdem zeigt sie, wie die Pufferung funktioniert.";
 
//Puffer leeren und Anzeige auf dem Bildschirm
ob_end_flush();

Nun kommen wir zum Problem dieses Beitrags. Man liest recht viel im Web, dass die Ausgabepufferung ziemlich große Geschwindigkeitsvorteile bietet, unter anderem im PHP Manual über Ausgabesteuerung (in den Kommentaren) oder einigen Blogs. Ich weiß nicht, ob sich die dort gemachten Aussagen auf Benchmarks beziehen oder ob wirklich Geschwindigkeitsvorteile von den Autoren erzielt worden. Ich konnte leider keinen Geschwindigkeitsvorteil feststellen.

Datei Gesamtlaufzeit durchschnittliche Laufzeit pro Durchlauf Verhältnis zur schnellsten Variante
result_ausgabe_
normal.php
227.817586 s 22.782 ms 100 %
result_ausgabe_
buffered.php
325.488029 s 32.549 ms 142 % (+ 42%)
result_ausgabe_
onevar.php
333.209131 s 33.321 ms 146 % (+ 46%)

In der php.ini steht auch, dass der Vortiel von Output-Bufferung ist, dass man setcookie() und andere den Header beeinflussende Funktionen noch aufrufen kann, obwohl die erste Ausgabe bereits gemacht wurde, was sonst nicht geht. Und es steht auch da, dass dieser Vorteil sich auf Kosten der Geschwindigkeit auswirkt.
Ich habe es dann noch einmal mit der ausgabe_normal.php und in der php.ini aktiviertem output buffering versucht und kam auf 23,745 ms pro Durchlauf. Das ist zwar in Reichweite des Wertes ohne output puffering, trotzdem kann ich die Berichte im Web leider nicht bestätigen. Aber bitte probiert es aus, irgendwo muss ich eine Fehlerquelle haben, denn ich kann mir kaum vorstellen, dass sich so viele Seiten im Web irren.
Wenn ihr wisst, woran das liegt, schaut euch bitte meine Quellcodes und die Benchmarks an und sendet einen Kommentar.

Jan hat 152 Beiträge geschrieben

7 Kommentare zu “Pufferung von Ausgaben

  1. Heiko sagt:

    Hast du in der langen Zeit die ja nun vergangen ist hier nochmal nachgesehen, weshalb du zu anderen Ergebnissen kommst wie der Rest der Welt? 😉

  2. Ren van Hoek sagt:

    Hallo,

    mich würde auch interessieren ob Du rausgefunden hast wieso deine Ergebnisse andere sind als bei einigen Blogs und Seiten.

  3. RedTuesday sagt:

    Es ist zwar nur subjektiv, aber bei einem älteren Projekt von mir habe ich eine größere, variable, Tabelle ausgegeben, und mit Puffer war der Seitenaufbau deutlich angenehmer als ohne.

  4. orancloud sagt:

    bedenkt,dass der puffer komprimierend wirkt. zum testen eignen sich desshalb nur entfernte server und grössere datein, auch brauch der server mehr prozessorleistung als ohne die komprimierung.
    also kann dieser performanceschub schon stimmen.

  5. Die Funktion macht vor allem dann Sinn, wenn man eine Ausgabe in eine Variable setzen will, um sie an anderer Stelle wieder auszugeben:

    // hier wird der puffer gefüllt
    ob_start();
    echo ‚Dies ist der Inhalt, der alles mögliche enthalten kann, auch includes anderer Scripte etc.‘;

    // hier wird der puffer in die variable übernommen und anschließend geleert (das is wichtig, ansonsten wird doppelt ausgegeben):
    $output = ob_get_contents();
    ob_end_clean();

    //irgendwo an anderer Stelle im Script:

    echo $output;

Eine Antwort schreiben

Ihre E-Mail-Adresse wird nicht veröffentlicht. Benötigte Felder sind markiert mit *

You may use these HTML tags and attributes: <a href=""> <blockquote cite=""> <pre lang=""> <b> <strong> <i> <em>