Wie man die Effizienz von PHP-Skripten bewertet

131

Ich möchte wissen, wie ich meine PHP-Skripte am besten vergleichen kann. Es spielt keine Rolle, ob es sich um einen Cron-Job, eine Webseite oder einen Webdienst handelt.

Ich weiß, dass ich Microtime verwenden kann, aber gibt es mir wirklich die Echtzeit eines PHP-Skripts?

Ich möchte verschiedene Funktionen in PHP testen und vergleichen, die dasselbe tun. Zum Beispiel preg_matchvs strposoder domdocumentvs preg_matchoder preg_replace vs str_replace`

Beispiel einer Webseite:

<?php
// login.php

$start_time = microtime(TRUE);

session_start(); 
// do all my logic etc...

$end_time = microtime(TRUE);

echo $end_time - $start_time;

Dies wird ausgegeben: 0.0146126717 (variiert ständig - aber das ist der letzte, den ich bekommen habe). Dies bedeutet, dass die Ausführung des PHP-Skripts ungefähr 0,015 dauerte.

Gibt es einen besseren Weg?

Eric
quelle
Lesen Sie diesen Artikel: rakesh.sankar-b.com/2011/01/12/echo-print-which-is-fast-php - Ich hoffe, es hilft.
Rakesh Sankar
4
0,015 Sekunden. Die durchschnittliche Blinkgeschwindigkeit eines Auges beträgt 0,3 Sekunden. Müssen Sie diese Geschwindigkeit wirklich, wirklich, wirklich verbessern? Darf ich fragen, warum?
Ben
4
@ben das ist ein Beispiel, ich habe Seiten, die in 0,8 Sekunden mit über 50.000 Besuchern pro Stunde
geladen werden.
8
@MarcB Amazon hat anscheinend getestet und festgestellt, dass eine Verzögerung von 100 ms zu einem Umsatzrückgang von 1% führte. Das könnten Milliarden für eine große Website wie Amazon sein. highscalability.com/…
ceejayoz
1
@ceejayoz Ja, wenn Sie Amazon sind, dann ist das ein großes Problem, aber wenn Sie nicht, dann seien Sie vorsichtig, wenn Sie nur verrückte Ladezeiten für Seiten verfolgen. Amazon hat seine Hausaufgaben gemacht und kann daher leicht rechtfertigen, X Mannstunden zu investieren, um Y Umsatzrückgänge zurückzugewinnen. Die Lektion hier ist, deine eigenen Hausaufgaben zu machen!
James Butler

Antworten:

122

Wenn Sie tatsächlich Code aus der realen Welt vergleichen möchten, verwenden Sie Tools wie Xdebug und XHProf .

Xdebug eignet sich hervorragend für die Arbeit mit Dev / Staging. XHProf ist ein hervorragendes Tool für die Produktion und kann dort sicher ausgeführt werden (solange Sie die Anweisungen lesen). Die Ergebnisse eines einzelnen Seitenladevorgangs sind nicht so relevant wie die Leistung Ihres Codes, während der Server dazu gebracht wird, eine Million anderer Dinge zu tun, und die Ressourcen knapp werden. Dies wirft eine andere Frage auf: Haben Sie einen Engpass bei der CPU? RAM? I / O?

Sie müssen auch über den Code hinaussehen, den Sie in Ihren Skripten ausführen, um zu sehen, wie Ihre Skripte / Seiten bereitgestellt werden. Welchen Webserver verwenden Sie? Als Beispiel kann ich nginx + PHP-FPM dazu bringen, mod_php + Apache ernsthaft auszuführen, was wiederum dazu führt, dass statische Inhalte mithilfe eines guten CDN bereitgestellt werden.

Als nächstes sollten Sie berücksichtigen, wofür Sie optimieren möchten.

  • Ist die Geschwindigkeit, mit der die Seite im Browser des Benutzers gerendert wird, die Priorität Nummer eins?
  • Ist es das Ziel, jede Anforderung an den Server so schnell wie möglich mit dem geringsten CPU-Verbrauch zurückzusenden?

Ersterem kann geholfen werden, indem beispielsweise alle an den Browser gesendeten Ressourcen komprimiert werden. Dies kann Sie jedoch (unter bestimmten Umständen) weiter vom Erreichen des letzteren abbringen.

Hoffentlich kann all dies dazu beitragen, zu zeigen, dass sorgfältig isolierte Labortests nicht die Variablen und Probleme widerspiegeln, auf die Sie in der Produktion stoßen, und dass Sie herausfinden müssen, was Ihr übergeordnetes Ziel ist und was Sie dann tun können, um dorthin zu gelangen. bevor Sie den Weg der Mikro- / Frühoptimierung zur Hölle beschreiten .

James Butler
quelle
6
Wenn dies Ihre Frage wirklich beantwortet, habe ich das Gefühl, dass Ihre Fragen falsch formuliert wurden (oder ich habe sie einfach falsch gelesen). Basierend auf Ihrer Frage klang es so, als wollten Sie verschiedene Methoden isolieren, um dasselbe in PHP zu tun und herauszufinden, welche die schnellste ist. Basierend auf den Antworten, die Sie akzeptiert und das Kopfgeld gegeben haben, scheint es jedoch, dass Sie mehr daran interessiert waren, Lasttests für den gesamten Webstack durchzuführen - was etwas völlig anderes ist.
Alec-Schlucht
Xdebug unterstützt keine Ioncube-codierten Skripte. Wie können Sie dieses Skript bewerten?
BigSack
@BigSack Du bist dort irgendwie alleine, ich habe noch nie versucht, etwas zu profilieren, das so verschleiert ist. Ich würde zuerst einen Versuch mit XHProf machen, da dies relativ einfach zum Laufen zu bringen ist. Möglicherweise stört IonCube vollständig mit jedem Nicht-Userland-Profiler.
James Butler
Die Aussage von Nginx vs Apache ist etwas voreingenommen. Die meisten vernachlässigen es, AllowOveridedass Apache bei jeder Anforderung ganze Verzeichnisse nach .htaccess-Dateien durchsucht. Dies allein bringt Apache aus dem Weg.
B00MER
74

Um zu messen, wie schnell Ihr komplettes Skript auf dem Server ausgeführt wird, können Sie zahlreiche Tools verwenden. Stellen Sie zunächst sicher, dass Ihr Skript (z. B. preg_match vs strpos) dieselben Ergebnisse ausgeben muss, um Ihren Test zu qualifizieren.

Sie können verwenden:

Buch des Zeus
quelle
30

Sie sollten sich Xdebug und insbesondere die Profilierungsfunktionen von Xdebug ansehen .

Grundsätzlich aktivieren Sie den Profiler und jedes Mal, wenn Sie eine Webseite laden, wird eine Cachegrind-Datei erstellt, die mit WinCacheGrind oder KCacheGrind gelesen werden kann .

Die Konfiguration von Xdebug kann etwas schwierig sein. Hier ist der relevante Abschnitt von my php.inials Referenz:

[XDebug]
zend_extension = h:\xampp\php\ext\php_xdebug-2.1.1-5.3-vc6.dll
xdebug.remote_enable=true
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_dir=h:\xampp\cachegrind
xdebug.profiler_output_name=callgrind.%t_%R.out

Und hier ist ein Screenshot einer .outDatei in WinCacheGrind :

Geben Sie hier die Bildbeschreibung ein

Das sollte reichlich Details darüber liefern, wie effizient Ihr PHP-Skript es ist. Sie möchten auf die Dinge abzielen, die die meiste Zeit in Anspruch nehmen. Sie könnten beispielsweise eine Funktion optimieren, um die Hälfte der Zeit in Anspruch zu nehmen, aber Ihre Bemühungen wären besser geeignet, um eine Funktion zu optimieren, die während eines Seitenladens Dutzende, wenn nicht Hunderte Male aufgerufen wird.

Wenn Sie neugierig sind, ist dies nur eine alte Version eines CMS, das ich für meinen eigenen Gebrauch geschrieben habe.

Alec-Schlucht
quelle
8
scheinen sehr kompliziert zu sein, ich verstehe nichts
eric
Welchen Teil verstehst du nicht? Das Setup oder die Analyse der Daten?
Alec Gorge
1
auch das Setup nein, das wird nie funktionieren auf meinem Server , aber die gespeicherten Daten, die alle kleine Kisten kann ich nicht lesen
eric
13
weil ich kein Windows
benutze
2
+1 für XDebug + KCacheGrind. Es ist sehr hilfreich und überraschend einfach zu installieren und zu verwenden. Ich benutze es schon seit einiger Zeit, ein zusätzlicher Bonus, den Sie erhalten - wenn Sie damit vertraut werden, können Sie KCacheGrind mit Valgrind (+ memgrind / callgrind) verwenden, um viel mehr andere Sprachen (und nicht nur die CPU-Zeit) zu profilieren.
XzKto
16

Versuchen Sie es mit https://github.com/fotuzlab/appgati

Es ermöglicht das Definieren von Schritten im Code und meldet Zeit, Speichernutzung, Serverlast usw. zwischen zwei Schritten.

Etwas wie:

    $appgati->Step('1');

    // Do some code ...

    $appgati->Step('2');

    $report = $appgati->Report('1', '2');
    print_r($report);

Beispielausgabearray:

Array
(
    [Clock time in seconds] => 1.9502429962158
    [Time taken in User Mode in seconds] => 0.632039
    [Time taken in System Mode in seconds] => 0.024001
    [Total time taken in Kernel in seconds] => 0.65604
    [Memory limit in MB] => 128
    [Memory usage in MB] => 18.237907409668
    [Peak memory usage in MB] => 19.579357147217
    [Average server load in last minute] => 0.47
    [Maximum resident shared size in KB] => 44900
    [Integral shared memory size] => 0
    [Integral unshared data size] => 0
    [Integral unshared stack size] => 
    [Number of page reclaims] => 12102
    [Number of page faults] => 6
    [Number of block input operations] => 192
    [Number of block output operations] => 
    [Number of messages sent] => 0
    [Number of messages received] => 0
    [Number of signals received] => 0
    [Number of voluntary context switches] => 606
    [Number of involuntary context switches] => 99
)
fotuzlab
quelle
2
Schönes Interface-Design (wie ich sehe, Sie sind der Autor), danke! (Und danke für die Verwendung von "ProperCase";) Methodennamen (wie SetMemory()) anstelle des hässlichen, aber immer noch allgegenwärtigen mixedCase()Mistes, der in PHP sowieso praktisch sinnlos ist. Du bist wahrscheinlich zu alt. ;))
Sz.
1
Völlig veraltet, aber mit ein paar Minuten habe ich daraus etwas Nettes und Nützliches gemacht (sogar in Fenstern). Ich werde versuchen zu sehen, ob ich eine Pull-Anfrage stellen kann.
Tomas Gonzalez
7

Ich würde in xhprof schauen . Es spielt keine Rolle, ob es auf dem CLI oder über ein anderes Sapi (wie fpm oder fcgi oder sogar das Apache-Modul) ausgeführt wird.

Das Beste an xhprof ist, dass es sogar fit genug ist, um in der Produktion ausgeführt zu werden. Etwas, das mit xdebug nicht so gut funktioniert (das letzte Mal, als ich es überprüft habe). xdebug wirkt sich auf die Leistung aus und xhprof (ich würde nicht sagen, dass es keine gibt) schafft es viel besser.

Wir verwenden häufig xhprof, um Proben mit echtem Datenverkehr zu sammeln und dann den Code von dort zu analysieren.

Es ist nicht wirklich ein Maßstab in Bezug darauf, dass Sie eine Zeit bekommen und all das bekommen, obwohl es das auch tut. Es macht es einfach sehr einfach, den Produktionsverkehr zu analysieren und dann im gesammelten Callgraph einen Drilldown auf die PHP-Funktionsebene durchzuführen.

Sobald die Erweiterung kompiliert und geladen ist, beginnen Sie mit der Profilerstellung im Code mit:

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

Stoppen:

$xhprof_data = xhprof_disable();

Speichern Sie dann die Daten in einer Datei oder Datenbank - was auch immer Ihr Boot schwebt und die übliche Laufzeit nicht unterbricht. Wir senden dies asynchron an S3, um die Daten zu zentralisieren (um alle Läufe von allen unseren Servern sehen zu können).

Der Code auf github enthält einen Ordner xhprof_html, den Sie auf dem Server sichern. Mit minimaler Konfiguration können Sie die gesammelten Daten visualisieren und mit dem Drilldown beginnen.

HTH!

Bis
quelle
3

Setzen Sie es in eine forSchleife, um jede Sache 1.000.000 Mal zu tun, um eine realistischere Zahl zu erhalten. Starten Sie den Timer erst kurz vor dem Code, den Sie tatsächlich messen möchten, und zeichnen Sie dann die Endzeit kurz danach auf (dh starten Sie den Timer nicht vor demsession_start() .

Stellen Sie außerdem sicher, dass der Code für jede Funktion, die Sie bewerten möchten, identisch ist, mit Ausnahme der Funktion, die Sie steuern.

Die Ausführung des Skripts (Cronjob, PHP über die Befehlszeile, Apache usw.) sollte keinen Unterschied machen, da Sie nur den relativen Unterschied zwischen der Geschwindigkeit der verschiedenen Funktionen zeitlich festlegen. Dieses Verhältnis sollte also gleich bleiben.

Wenn auf dem Computer, auf dem Sie den Benchmark ausführen, viele andere Dinge ausgeführt werden, kann dies die Benchmark-Ergebnisse beeinflussen, wenn die CPU- oder Speicherauslastung einer anderen Anwendung während der Ausführung Ihres Benchmarks ansteigt. Aber solange Sie eine Menge Ressourcen auf dem Computer haben, denke ich nicht, dass dies ein Problem sein wird.

Alasdair
quelle
1

Ein guter Anfang ist die Verwendung des xdebugs-Profilers http://xdebug.org/docs/profiler

Vielleicht nicht die einfachste Einrichtung und Verwendung, aber sobald Sie sie in Betrieb genommen haben, sind die Datenmengen und die einfache Anzeige unersetzlich.

Ziege
quelle
0

Eric,

Sie stellen sich die falsche Frage. Wenn Ihr Skript in ~ 15 mSec ausgeführt wird, ist seine Zeit weitgehend irrelevant. Wenn Sie auf einem gemeinsam genutzten Dienst ausgeführt werden, dauert die Aktivierung des PHP-Images ~ 100 mSec, wobei die Skriptdateien ~ 30-50 mSec eingelesen werden, wenn sie vollständig auf dem Server zwischengespeichert sind, möglicherweise 1 oder mehr Sekunden, wenn sie von einer Backend-NAS-Farm geladen werden. Netzwerkverzögerungen beim Laden der Seitenmöbel können viele Sekunden hinzufügen.

Das Hauptproblem hierbei ist die Wahrnehmung der Ladezeit durch den Benutzer: Wie lange muss er zwischen dem Klicken auf den Link und dem Abrufen einer vollständig gerenderten Seite warten? Schauen Sie sich Google Page Speed ​​an, das Sie als Ff- oder Chrome-Erweiterung verwenden können, und die Pagespeed-Dokumentation, in der ausführlich erläutert wird, wie Sie eine gute Seitenleistung erzielen. Befolgen Sie diese Richtlinien und versuchen Sie, Ihre Seitenwerte besser als 90/100 zu erzielen. (Die Google-Startseite erreicht 99/100 Punkte, ebenso wie mein Blog). Dies ist der beste Weg, um eine vom Benutzer wahrgenommene Leistung zu erzielen.

TerryE
quelle
0

Es ist auch gut, den PHP-Code im Auge zu behalten und mit diesem Link zu überprüfen , um sicherzustellen, dass Ihre Codierung selbst die Leistung der App möglicherweise nicht beeinträchtigt.

Ritesh Aryal
quelle