smart | Webentwicklung
Alles rund um HTML5, PHP, WordPress & Co.

Performance-Profiling in PHP mit XHProf

26. April 2012
Stephan
PHP

Ein entscheidenes Qualitätsmerkmal und somit wichtiges Kriterium für Webapplikationen ist im Allgemeinen die Performance.

Um Performance-Bremsen im Code bzw. in einer Software zu finden, haben sich sogenannte Profiler als nützlich erwiesen, welche den Code zur Laufzeit analysieren. Hierdurch kann festgestellt werden, welche Teile des Codes z.B. wie viel Zeit und Speicher benötigen und performancelastige Codestellen können basierend auf den gewonnen Daten optimiert werden.

Im PHP-Bereich gibt es z.B. das bekannte PHP-Profiling- und Debugger-Tool XDebug. In diesem Artikel möchte ich euch jedoch das PHP-Profiling-Tool XHProf vorstellen.

Was ist XHProf?

XHProf ist ein Profiling-Tool für PHP, welches ursprünglich von Facebook entwickelt und im Jahre 2009 von ihnen als Open-Source freigegeben wurde.

Wie andere gängige Profiling-Tools analysiert XHProf, wie lange z.B. eine Funktion ausgeführt wurde und wieviel Speicher diese Funktion genutzt hat.

Im Gegensatz zu XDebug bietet es aber zusätzlich die Möglichkeit an, zwei Profiling-Runs (Durchläufe) direkt miteinander zu vergleichen.

Installation

Die folgenden Installationsanweisung bezieht sich auf die Installation von XHProf unter Ubuntu (11.10) und basiert nicht auf der aktuellsten XHProf-Version.

Die aktuellste Version von XHProf könnt ihr direkt von GitHub herunterladen: XHProf.

Als erstes rufen wir unser Terminal auf und geben Folgendes ein:

cd /opt/
sudo wget http://pecl.php.net/get/xhprof-0.9.2.tgz
sudo tar xvf xhprof-0.9.2.tgz
cd xhprof-0.9.2/extension/
sudo phpize
sudo ./configure --with-php-config=/usr/bin/php-config
sudo make
sudo make install
sudo make test

Falls ihr eine Fehlermeldung bekommt, dass phpize nicht gefunden wurde, müsst ihr zuvor noch ein zusätzliches Paket installieren:

sudo apt-get install php5-dev

Im nächsten Schritt müssen wir unsere PHP-Konfigurationsdatei anpassen und rufen sie deshalb wie folgt auf:

sudo gedit /etc/php5/apache2/php.ini

Am Ende der Datei fügen wir nun folgende Zeilen hinzu:

[xhprof]
extension = xhprof.so
xhprof.output_dir="/tmp"

Abschließend starten wir unseren Apache neu, damit die Änderungen wirksam werden:

sudo /etc/init.d/apache2 restart

Wenn alles reibungslos funktioniert hat, ist XHProf nun einsatzbereit. Zum Sicherstellen, dass die XHProf-Erweiterung auch wirklich geladen wird, könnt ihr eine PHP-Datei anlegen, die euch eure PHP-Einstellungen anzeigt:

<? phpinfo(); ?>

Diese Datei ruft ihr dann einfach in eurem Webbrowser auf und schaut, ob XHProf aufgelistet ist.

XHProf in Aktion – Code profilen

Nun können wir mittels XHProf jeden beliebigen Code profilen und analysieren. Als Beispielgrundlage nehme ich einfach mal das gegebene Beispiel aus der Doku.

Dafür legen wir im Verzeichnis /var/www/ die Datei xhprof_test.php an und fügen folgenden Code ein:

<?php
function bar($x) 
{
    if ($x > 0) 
    {
        bar($x - 1);
    }
}
 
function foo() {
    for ($idx = 0; $idx < 2; $idx++)
    {
        bar($idx);
        $x = strlen("abc");
    }
}
 
// Profiling-Start
// xhprof_enable() - normaler Aufruf
// die Argumente geben an, dass wir CPU und Memory-Verbrauch auch ermitteln wollen
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
 
// der eigentliche Code zum Profilen
foo();
 
// Profiling-Ende
$xhprof_data = xhprof_disable();
 
// Profiling-Daten-Array anzeigen
echo "<pre>";
print_r($xhprof_data);
echo "</pre>";
 
// einbinden der GUI-Dateien von XHProf
include_once "xhprof_lib/utils/xhprof_lib.php";
include_once "xhprof_lib/utils/xhprof_runs.php";
 
$xhprof_runs = new XHProfRuns_Default();
 
// speichern der Daten - gibt die dazugehörige Run-ID zurück
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");
 
// Link zur GUI-Seite
echo '<a href="http://localhost/xhprof_html/index.php?run='.$run_id.'&source=xhprof_foo">Profiling Data</a>';
?>

Nun müssen wir doch noch mal im Terminal Hand anlegen und zwei Symlinks setzen:

cd /var/www/
sudo ln -s /opt/xhprof-0.9.2/xhprof_html/ ./
sudo ln -s /opt/xhprof-0.9.2/xhprof_lib/ ./

Anschließend rufen wir unsere xhprof_test.php in unserem Webbrowser auf und sollten einen Link sehen, der uns zur Auswertungsseite leitet. Im Folgenden ein kleiner Ausschnitt aus der Auswertung:

XHProf - Profiling-Auswertung

Die einzelnen Funktionen könnt ihr auch noch im Detail ansehen. Dann ist auch ersichtlich, was genau in einer Funktion, wie lange gedauert hat und ihr könnt euch auch einen dazugehörigen Callgraph anzeigen lassen.

Außerdem wird auch angezeigt, wie viel Speicher die jeweilige Funktion benötigt hat.

Code-Vergleich mittels Diffs

Wenn wir zwei Profiling-Runs (Durchläufe) miteinander vergleichen wollen, müssen wir nur in unserem Webbrowser Folgendes eingeben:

http://<xhprof-ui-address>/index.php?run1=<run_id1>&run2=<run_id2>&source=<namespace>

Für unser Beispiel könnte dieses so aussehen:

http://localhost/xhprof_html/index.php?run1=4d03a2382f6c6&run2=4d03a23fb5dca&source=xhprof_foo

Die XHProf-Dateien werden in unserem Fall im Verzeichnis /tmp abgespeichert. Dabei ist in im Dateinamen auch immer die jeweilige Run-ID vorhanden.

Ein Ausschnitt aus dem dadurch generierten Diff, könnte wie folgt aussehen:

XHProf - Profiling-Diff-Auswertung

Die roten Werte zeigen an, dass im Vergleich zum vorherigen Run die Perormance schlechter ist und grüne Werte bedeuteten eine Performance-Verbesserung. Dieser Ausschnitt zeigt jedoch nur den direkten Vergleich der Funktionen, aber es gibt natürlich auch einen Gesamtvergleich der zwei Runs zu sehen.

Weitere nützliche Einstellungsmöglichkeiten

Grundsätzlich gibt es noch einige Einstellungsmöglichkeiten für XHProf, die beeinflussen, was genau analysiert bzw. ausgewertet werden soll. Beispielsweise kann angegeben werden, welche Funktionen von der Auswertung ausgeschlossen werden sollen:

xhprof_enable(0, array('ignored_functions' =>  array('call_user_func', 'call_user_func_array')));

Weiterhin ist es möglich, die Standard-PHP-Funktionen generell auszuschließen:

xhprof_enable(XHPROF_FLAGS_NO_BUILTINS);

Fazit

Mit XHProf gibt es für PHP ein gutes Tool zum Profilen des eigenes Codes, wodurch eventuelle Performance-Bremsen leichter gefunden werden können.

Der Vorteil liegt für mich bei XHProf darin, dass ich über Diffs zwei Runs miteinander vergleichen kann und so wirklich im direkten Vergleich sehe, ob meine Optimierungen was bringen oder nicht. Nachteil ist jedoch, dass die Benutzeroberfläche recht spartanisch ist und das man es nicht, wie z.B. bei XDebug, in bestehende Entwicklungsumgebungen (z.B. Eclipse, PHPStorm etc.) integrieren kann.

Kanntet ihr XHProf bereits und habt schon Erfahrungen sammeln können? Habt ihr schon mal mit einem Code-Profiler gearbeitet?

Kommentare  
0 Kommentare vorhanden
0 Trackbacks/Pingbacks vorhanden
Du bist herzlich eingeladen auch ein Kommentar zu hinterlassen!
Kommentar schreiben

Vielen Dank für dein Kommentar!