Frage

Was ist der einfachste Weg, ein PHP-Skript zu profilieren?

Ich würde gerne etwas anbringen, das mir einen Dump aller Funktionsaufrufe und deren Dauer zeigt, aber ich bin auch damit einverstanden, etwas um bestimmte Funktionen herum zu machen.

Ich habe versucht, damit zu experimentieren Mikrozeit Funktion:

$then = microtime();
myFunc();
$now = microtime();

echo sprintf("Elapsed:  %f", $now-$then);

aber das führt manchmal zu negativen Ergebnissen.Außerdem ist es sehr mühsam, das über meinen gesamten Code zu verteilen.

War es hilfreich?

Lösung

Der PECL APD Die Erweiterung wird wie folgt verwendet:

<?php
apd_set_pprof_trace();

//rest of the script
?>

Analysieren Sie anschließend die generierte Datei mit pprofp.

Beispielausgabe:

Trace for /home/dan/testapd.php
Total Elapsed Time = 0.00
Total System Time  = 0.00
Total User Time    = 0.00


Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0009            0 main
56.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0005   0.0005            0 apd_set_pprof_trace
28.0 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 preg_replace
14.3 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 str_replace

Warnung:Die neueste Version von APD ist aus dem Jahr 2004, die Erweiterung wird nicht mehr gepflegt und weist verschiedene Kompatibilitätsprobleme auf (siehe Kommentare).

Andere Tipps

Sie wollen xdebug Ich finde.Installieren Sie es auf dem Server, schalten Sie es ein und pumpen Sie die Ausgabe durch kcachegrind (für Linux) oder wincachegrind (für Windows) und es werden Ihnen ein paar hübsche Diagramme angezeigt, die die genauen Zeiten, Anzahlen und Speichernutzung detailliert beschreiben (dafür benötigen Sie jedoch eine weitere Erweiterung).

Es rockt, im Ernst :D

Es sind keine Erweiterungen erforderlich. Nutzen Sie einfach diese beiden Funktionen zur einfachen Profilerstellung.

// Call this at each point of interest, passing a descriptive string
function prof_flag($str)
{
    global $prof_timing, $prof_names;
    $prof_timing[] = microtime(true);
    $prof_names[] = $str;
}

// Call this when you're done and want to see the results
function prof_print()
{
    global $prof_timing, $prof_names;
    $size = count($prof_timing);
    for($i=0;$i<$size - 1; $i++)
    {
        echo "<b>{$prof_names[$i]}</b><br>";
        echo sprintf("&nbsp;&nbsp;&nbsp;%f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
    }
    echo "<b>{$prof_names[$size-1]}</b><br>";
}

Hier ist ein Beispiel, bei dem prof_flag() mit einer Beschreibung an jedem Prüfpunkt und prof_print() am Ende aufgerufen wird:

prof_flag("Start");

   include '../lib/database.php';
   include '../lib/helper_func.php';

prof_flag("Connect to DB");

   connect_to_db();

prof_flag("Perform query");

   // Get all the data

   $select_query = "SELECT * FROM data_table";
   $result = mysql_query($select_query);

prof_flag("Retrieve data");

   $rows = array();
   $found_data=false;
   while($r = mysql_fetch_assoc($result))
   {
       $found_data=true;
       $rows[] = $r;
   }

prof_flag("Close DB");

   mysql_close();   //close database connection

prof_flag("Done");
prof_print();

Die Ausgabe sieht so aus:

Start
   0.004303
Mit DB verbinden
   0.003518
Abfrage durchführen
   0.000308
Daten abrufen
   0.000009
DB schließen
   0.000049
Erledigt

Cross-Posting meiner Referenz aus der Beta-Version der SO-Dokumentation, die offline geht.

Profilerstellung mit XDebug

Zur Unterstützung steht eine PHP-Erweiterung namens Xdebug zur Verfügung Profilierung von PHP-Anwendungen, sowie Laufzeit-Debugging.Beim Ausführen des Profilers wird die Ausgabe in eine Datei in einem Binärformat namens „cachegrind“ geschrieben.Auf jeder Plattform stehen Anwendungen zur Analyse dieser Dateien zur Verfügung. Zur Durchführung dieser Profilerstellung sind keine Änderungen am Anwendungscode erforderlich.

Um die Profilerstellung zu aktivieren, installieren Sie die Erweiterung und passen Sie die php.ini-Einstellungen an.Einige Linux-Distributionen enthalten Standardpakete (z. B.Ubuntus php-xdebug Paket).In unserem Beispiel führen wir das Profil optional basierend auf einem Anforderungsparameter aus.Dadurch können wir die Einstellungen statisch halten und den Profiler nur bei Bedarf aktivieren.

# php.ini settings
# Set to 1 to turn it on for every request
xdebug.profiler_enable = 0
# Let's use a GET/POST parameter to turn on the profiler
xdebug.profiler_enable_trigger = 1
# The GET/POST value we will pass; empty for any value
xdebug.profiler_enable_trigger_value = ""
# Output cachegrind files to /tmp so our system cleans them up later
xdebug.profiler_output_dir = "/tmp"
xdebug.profiler_output_name = "cachegrind.out.%p"

Verwenden Sie als Nächstes einen Web-Client, um eine Anfrage an die URL Ihrer Anwendung zu stellen, die Sie profilieren möchten, z. B.

http://example.com/article/1?XDEBUG_PROFILE=1

Während die Seite verarbeitet wird, schreibt sie in eine Datei mit einem Namen wie

/tmp/cachegrind.out.12345

Standardmäßig ist die Zahl im Dateinamen die Prozess-ID, die sie geschrieben hat.Dies ist mit dem konfigurierbar xdebug.profiler_output_name Einstellung.

Beachten Sie, dass für jede ausgeführte PHP-Anfrage/jeden PHP-Prozess eine Datei geschrieben wird.Wenn Sie beispielsweise einen Formularbeitrag analysieren möchten, wird ein Profil für die GET-Anfrage geschrieben, um das HTML-Formular anzuzeigen.Der Parameter XDEBUG_PROFILE muss an die nachfolgende POST-Anfrage übergeben werden, um die zweite Anfrage zu analysieren, die das Formular verarbeitet.Daher ist es bei der Profilerstellung manchmal einfacher, Curl auszuführen, um ein Formular direkt zu posten.

Analysieren der Ausgabe

Sobald der Profilcache geschrieben ist, kann er von einer Anwendung wie z. B. gelesen werden KCachegrind oder Webgrind.PHPStorm, eine beliebte PHP-IDE, kann dies auch diese Profilierungsdaten anzeigen.

KCachegrind

KCachegrind zeigt beispielsweise folgende Informationen an:

  • Ausgeführte Funktionen
  • Aufrufzeit, sowohl selbst als auch einschließlich nachfolgender Funktionsaufrufe
  • Häufigkeit, mit der jede Funktion aufgerufen wird
  • Rufen Sie Diagramme auf
  • Links zum Quellcode

Wonach schauen

Offensichtlich ist die Leistungsoptimierung sehr spezifisch für die Anwendungsfälle jeder Anwendung.Im Allgemeinen ist es gut, nach Folgendem zu suchen:

  • Wiederholte Aufrufe derselben Funktion, die Sie nicht erwarten würden.Für Funktionen, die Daten verarbeiten und abfragen, könnten dies erstklassige Möglichkeiten für die Zwischenspeicherung Ihrer Anwendung sein.
  • Langsam laufende Funktionen.Wo verbringt die Anwendung die meiste Zeit?Der beste Nutzen bei der Leistungsoptimierung besteht darin, sich auf die Teile der Anwendung zu konzentrieren, die die meiste Zeit in Anspruch nehmen.

Notiz:Xdebug und insbesondere seine Profilierungsfunktionen sind sehr ressourcenintensiv und verlangsamen die PHP-Ausführung.Es wird empfohlen, diese nicht in einer Produktionsserverumgebung auszuführen.

Wenn das Subtrahieren von Mikrozeiten zu negativen Ergebnissen führt, versuchen Sie es mit der Funktion mit dem Argument true (microtime(true)).Mit true, gibt die Funktion einen Float anstelle eines Strings zurück (wie es der Fall ist, wenn sie ohne Argumente aufgerufen wird).

Ehrlich gesagt behaupte ich, dass die Verwendung von NewRelic für die Profilerstellung am besten ist.

Es handelt sich um eine PHP-Erweiterung, die die Laufzeit scheinbar überhaupt nicht verlangsamt. Sie übernimmt die Überwachung für Sie und ermöglicht so einen ordentlichen Drilldown.In der teuren Version ermöglichen sie umfangreiche Drilldowns (aber wir können uns ihr Preismodell nicht leisten).

Dennoch ist es selbst beim kostenlosen/Standard-Plan offensichtlich und einfach, wo die meisten niedrig hängenden Früchte liegen.Mir gefällt auch, dass es Ihnen auch eine Vorstellung von DB-Interaktionen geben kann.

screenshot of one of the interfaces when profiling

PECL XHPROF sieht auch interessant aus.Es hat anklickbare HTML-Schnittstelle zum Anzeigen von Berichten und ziemlich einfach Dokumentation.Ich muss es allerdings noch testen.

Profilierung des armen Mannes, keine Erweiterungen erforderlich.Unterstützt verschachtelte Profile und Prozentsatz der Gesamtsumme:

function p_open($flag) {
    global $p_times;
    if (null === $p_times)
        $p_times = [];
    if (! array_key_exists($flag, $p_times))
        $p_times[$flag] = [ 'total' => 0, 'open' => 0 ];
    $p_times[$flag]['open'] = microtime(true);
}

function p_close($flag)
{
    global $p_times;
    if (isset($p_times[$flag]['open'])) {
        $p_times[$flag]['total'] += (microtime(true) - $p_times[$flag]['open']);
        unset($p_times[$flag]['open']);
    }
}

function p_dump()
{
    global $p_times;
    $dump = [];
    $sum  = 0;
    foreach ($p_times as $flag => $info) {
        $dump[$flag]['elapsed'] = $info['total'];
        $sum += $info['total'];
    }
    foreach ($dump as $flag => $info) {
        $dump[$flag]['percent'] = $dump[$flag]['elapsed']/$sum;
    }
    return $dump;
}

Beispiel:

<?php

p_open('foo');
sleep(1);
p_open('bar');
sleep(2);
p_open('baz');
sleep(3);
p_close('baz');
sleep(2);
p_close('bar');
sleep(1);
p_close('foo');

var_dump(p_dump());

Erträge:

array:3 [
  "foo" => array:2 [
    "elapsed" => 9.000766992569
    "percent" => 0.4736904954747
  ]
  "bar" => array:2 [
    "elapsed" => 7.0004580020905
    "percent" => 0.36841864946596
  ]
  "baz" => array:2 [
    "elapsed" => 3.0001420974731
    "percent" => 0.15789085505934
  ]
]

Ich verwende gerne phpDebug zur Profilerstellung.http://phpdebug.sourceforge.net/www/index.html

Es gibt die gesamte Zeit-/Speichernutzung für jedes verwendete SQL sowie alle enthaltenen Dateien aus.Offensichtlich funktioniert es am besten mit abstrahiertem Code.

Für die Funktions- und Klassenprofilierung verwende ich einfach microtime() + get_memory_usage() + get_peak_memory_usage().

Ich würde auf jeden Fall geben Schwarzes Feuer ein Versuch.

Es gibt diese VirtualBox, mit der ich zusammengestellt habe Puppet, um verschiedene PHP-Frameworks zu testen, die mit BlackFire geliefert werden, können Sie diese bei Bedarf gerne teilen und/oder verteilen :)

https://github.com/webit4me/PHPFrameworks

Für das Benchmarking verwende ich, wie in Ihrem Beispiel, das Birne Benchmark Paket.Sie setzen Markierungen zum Messen.Der Kurs stellt auch einige Präsentationshilfen zur Verfügung, oder Sie können die Daten nach Belieben bearbeiten.

Ich habe es tatsächlich in einer anderen Klasse mit einer __destruct-Methode verpackt.Wenn ein Skript beendet wird, wird die Ausgabe über log4php im Syslog protokolliert, sodass ich auf viele Leistungsdaten zurückgreifen kann.

XDebug ist nicht stabil und für bestimmte PHP-Versionen nicht immer verfügbar.Auf einigen Servern verwende ich beispielsweise immer noch PHP-5.1.6 – es ist das, was mit RedHat RHEL5 geliefert wird (und erhält übrigens immer noch Updates für alle wichtigen Probleme), und aktuelles XDebug lässt sich nicht einmal mit diesem PHP kompilieren.Also bin ich schließlich zu gewechselt DBG-DebuggerEs ist PHP-Benchmarking Bietet Timing für Funktionen, Methoden, Module und sogar Zeilen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top