Genaue Methode zum Messen der Ausführungszeiten von PHP-Skripten

269

Ich möchte wissen, wie viele Millisekunden eine PHP-for-Schleife benötigt, um ausgeführt zu werden.

Ich kenne die Struktur eines generischen Algorithmus, weiß aber nicht, wie ich ihn in PHP implementieren soll:

Begin
init1 = timer(); // where timer() is the amount of milliseconds from midnight
the loop begin
some code
the loop end
total = timer() - init1;
End
DomingoSL
quelle
Sie können mit einer Vielzahl von microtime () - Anweisungen herumspielen, wenn Sie dies in der Produktion benötigen. Wenn dies jedoch nur zum Testen dient, verwenden Sie beispielsweise den Profiler von xdebug . Kein unordentlicher Code ist ein echtes Plus.
Wrikken

Antworten:

523

Hierfür können Sie die microtimeFunktion verwenden. Aus der Dokumentation :

microtime - Aktuellen Unix-Zeitstempel mit Mikrosekunden zurückgeben


Wenn auf get_as_floatgesetzt ist, TRUEwird microtime()ein Float zurückgegeben, der die aktuelle Zeit in Sekunden seit der Unix-Epoche darstellt, die auf die nächste Mikrosekunde genau ist.

Anwendungsbeispiel:

$start = microtime(true);
while (...) {

}
$time_elapsed_secs = microtime(true) - $start;
Tim Cooper
quelle
36
Sie benötigen, microtime(true)wenn Sie Berechnungen mit dem Rückgabewert durchführen möchten.
einsamer
7
Ich weiß, dass dies waaaaaay zu spät ist (fast 4 Jahre), aber als Kommentar ... Wenn Sie diese Berechnungen (mit dem Parameter get_as_floatas true) verwenden, erhalten Sie laut PHP-Dokumentation Ergebnisse in Sekunden .
Alejandro Iván
6
@patrick und das ist , was ich gesagt: wenn get_as_floatist true, microtime()gibt den Wert , der die Sekunden ...
Alejandro Iván
2
Obwohl dies ein sehr alter Beitrag ist, sollten wir uns auf die Tatsache beziehen, dass der zurückgegebene Float die Mikrosekunden enthält ... Die beste Lösung besteht darin, dies um 1000 zu messen ... siehe stackoverflow.com/questions/3656713/… als Beispiel. .
Verärgerte 84
1
Diese Antwort ist veraltet. Heutzutage ist der beste Weg, um die Ausführungszeit eines Skripts zu melden, eine einzelne Zeile am Ende Ihres Codes: $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]; (Weitere Informationen in einer Antwort unten .)
ashleedawg
84

Sie können microtime(true)mit folgenden Manieren verwenden:

Setzen Sie dies am Anfang Ihrer PHP-Datei:

//place this before any script you want to calculate time
$time_start = microtime(true);

// Ihr Skriptcode geht hier

// do something

Fügen Sie dies am Ende Ihrer PHP-Datei ein:

// Display Script End time
$time_end = microtime(true);

//dividing with 60 will give the execution time in minutes other wise seconds
$execution_time = ($time_end - $time_start)/60;

//execution time of the script
echo '<b>Total Execution Time:</b> '.$execution_time.' Mins';

Es wird ausgegeben, was Sie ergeben minutes.

Aditya P Bhatt
quelle
72

Sie können REQUEST_TIMEaus dem $_SERVERsuperglobalen Array verwenden. Aus der Dokumentation :

REQUEST_TIME
Der Zeitstempel des Starts der Anforderung. (Verfügbar seit PHP 5.1.0.)

REQUEST_TIME_FLOAT
Der Zeitstempel des Starts der Anforderung mit einer Genauigkeit von Mikrosekunden . (Verfügbar seit PHP 5.4.0.)

Auf diese Weise müssen Sie am Anfang Ihres Skripts keinen Zeitstempel speichern. Sie können einfach tun:

<?php
// Do stuff
usleep(mt_rand(100, 10000));

// At the end of your script
$time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];

echo "Did stuff in $time seconds\n";
?>

Hier $timewürde die seit dem Start des Skripts verstrichene Zeit in Sekunden mit einer Genauigkeit von Mikrosekunden (z. B. 1.341für 1 Sekunde und 341 Mikrosekunden) enthalten sein.


Mehr Info:

PHP-Dokumentation : $_SERVERVariablen und microtimeFunktion

Iwazaru
quelle
Das ist praktisch zu wissen. Sie könnten also verwenden:$start = $_SERVER["REQUEST_TIME_FLOAT"]; $myscript = microtime(true); $bootstrap = $myscript - $start; ...do stuff ...; $myscripttime = microtime(true) - $myscript;
pspahn
1
Der springende Punkt bei der Verwendung ist, dass Sie einfach Folgendes tun können: $myscripttime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];am Ende Ihres Skripts, ohne am Anfang einen Zeitstempel speichern zu müssen.
Iwazaru
1
Enthält laut der verknüpften Dokumentation $timedie Differenz in Sekunden , nicht in Mikrosekunden .
Wim Deblauwe
4
@WimDeblauwe Zur Verdeutlichung, ja, das Ergebnis ist in Sekunden. Aber mit Mikrosekunde Präzision . 1.1entspricht zB 1 Sekunde + 100 Mikrosekunden.
Chris Harrison
1
Dies ist der beste Weg, um die Reaktionszeit zu messen
Mike Aron
27

Erstellen Sie die Datei loadtime.php

<?php
class loadTime{
    private $time_start     =   0;
    private $time_end       =   0;
    private $time           =   0;
    public function __construct(){
        $this->time_start= microtime(true);
    }
    public function __destruct(){
        $this->time_end = microtime(true);
        $this->time = $this->time_end - $this->time_start;
        echo "Loaded in $this->time seconds\n";
    }
}

Als am Anfang Ihres Skripts, nach dem <?phpSchreibeninclude 'loadtime.php'; $loadtime=new loadTime();

Wenn die Seite am Ende geladen wird, wird "In x Sekunden geladen" geschrieben.

Solo Omsarashvili
quelle
5
Ordentlich! Wenn Sie Ihr Objekt jedoch nicht explizit zerstören, wird die Ausgabe nach dem </html>ungültigen schließenden Tag
angezeigt
@gondo Nein, es wird Sekunden sein (mit Mikrosekunden ausgedrückt als Dezimalwerte von Sekunden)
FrancescoMM
19
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
    // do something
}
$total = microtime(true) - $start;
echo $total;
Dvir Azulay
quelle
7

Siehe microtime () .

Patapizza
quelle
7

Hier ist eine Funktion, die die Ausführung eines PHP-Codes zeitlich festlegt, ähnlich wie das Python-Timeit-Modul: https://gist.github.com/flaviovs/35aab0e85852e548a60a

Wie man es benutzt:

include('timeit.php');
const SOME_CODE = '
        strlen("foo bar");
';
$t = timeit(SOME_CODE);
print "$t[0] loops; $t[2] per loop\n";

Ergebnis:

$ php x.php 
100000 loops; 18.08us per loop

Haftungsausschluss: Ich bin der Autor dieses Gists

BEARBEITEN: timeit ist jetzt ein separates, eigenständiges Projekt unter https://github.com/flaviovs/timeit

Flaviovs
quelle
5

Sie haben die richtige Idee, außer dass mit der microtime () ein genaueres Timing verfügbar ist. Funktion .

Wenn das, was sich in der Schleife befindet, schnell ist, ist es möglich, dass die scheinbar verstrichene Zeit Null ist. Wenn ja, wickeln Sie eine weitere Schleife um den Code und rufen Sie ihn wiederholt auf. Teilen Sie die Differenz durch die Anzahl der Iterationen, um eine einmalige Zeit zu erhalten. Ich habe Code profiliert, für den 10.000.000 Iterationen erforderlich waren, um konsistente, zuverlässige Timing-Ergebnisse zu erzielen.

Wallyk
quelle
3

Ich dachte, ich würde die Funktion teilen, die ich zusammengestellt habe. Hoffentlich können Sie Zeit sparen.

Es wurde ursprünglich verwendet, um das Timing eines textbasierten Skripts zu verfolgen, sodass die Ausgabe in Textform erfolgt. Sie können es jedoch problemlos in HTML ändern, wenn Sie dies bevorzugen.

Es werden alle Berechnungen für Sie durchgeführt, um festzustellen, wie viel Zeit seit dem Start des Skripts und in jedem Schritt aufgewendet wurde. Es formatiert die gesamte Ausgabe mit 3 Dezimalstellen. (Bis auf Millisekunden.)

Sobald Sie es an den Anfang Ihres Skripts kopiert haben, müssen Sie nur die recordTime-Funktionsaufrufe nach jedem Stück setzen, das Sie zeitlich festlegen möchten.

Kopieren Sie dies an den Anfang Ihrer Skriptdatei:

$tRecordStart = microtime(true);
header("Content-Type: text/plain");
recordTime("Start");

function recordTime ($sName) {
  global $tRecordStart;
  static $tStartQ;
  $tS = microtime(true);
  $tElapsedSecs = $tS - $tRecordStart;
  $tElapsedSecsQ = $tS - $tStartQ;
  $sElapsedSecs = str_pad(number_format($tElapsedSecs, 3), 10, " ", STR_PAD_LEFT);
  $sElapsedSecsQ = number_format($tElapsedSecsQ, 3);
  echo "//".$sElapsedSecs." - ".$sName;
  if (!empty($tStartQ)) echo " In ".$sElapsedSecsQ."s";
  echo "\n";
  $tStartQ = $tS;
}

Um die verstrichene Zeit zu verfolgen, gehen Sie einfach wie folgt vor:

recordTime("What We Just Did")

Beispielsweise:

recordTime("Something Else")
//Do really long operation.
recordTime("Really Long Operation")
//Do a short operation.
recordTime("A Short Operation")
//In a while loop.
for ($i = 0; $i < 300; $i ++) {
  recordTime("Loop Cycle ".$i)
}

Gibt Ausgabe wie folgt:

//     0.000 - Start
//     0.001 - Something Else In 0.001s
//    10.779 - Really Long Operation In 10.778s
//    11.986 - A Short Operation In 1.207s
//    11.987 - Loop Cycle 0 In 0.001s
//    11.987 - Loop Cycle 1 In 0.000s
...
//    12.007 - Loop Cycle 299 In 0.000s

Hoffe das hilft jemandem!

Azoundria
quelle
2

Hier ist eine sehr einfache und kurze Methode

<?php
$time_start = microtime(true);
//the loop begin
//some code
//the loop end
$time_end = microtime(true);
$total_time = $time_end - $time_start;
echo $total_time; // or whatever u want to do with the time
?>
Deepak Kumar
quelle
Ich denke, du vermisst etwas, das ich getestet habe, als ich die Antwort gepostet habe
Deepak Kumar
var_dump (microtime (true)); // float (1283846202.89) das ist was, wenn du microtime true verwendest
Deepak Kumar
Sie können float auch in der Gesamtzeit verwenden
Deepak Kumar
2

Wenn Sie diese Zeit in Sekunden anzeigen möchten:

<?php
class debugTimer 
{
    private $startTime;
    private $callsCounter;

    function __construct() 
    {
        $this->startTime = microtime(true);
        $this->callsCounter = 0;
    }

    public function getTimer(): float
    {
        $timeEnd = microtime(true);
        $time = $timeEnd - $this->startTime;
        $this->callsCounter++;
        return $time;
    }

    public function getCallsNumer(): int
    {
        return $this->callsCounter;
    }
}

$timer = new debugTimer();
usleep(100);
echo '<br />\n
'.$timer->getTimer(). ' seconds before call #'.$timer->getCallsNumer();

usleep(100);
echo '<br />\n
'.$timer->getTimer(). ' seconds before call #'.$timer->getCallsNumer();
Eugene Kaurov
quelle
1

Hier ist eine Implementierung, die Sekundenbruchteile zurückgibt (dh 1,321 Sekunden).

/**
 * MICROSECOND STOPWATCH FOR PHP
 *
 * Class FnxStopwatch
 */
class FnxStopwatch
{
    /** @var float */
    private $start,
            $stop;

    public function start()
    {
        $this->start = self::microtime_float();
    }
    public function stop()
    {
        $this->stop = self::microtime_float();
    }
    public function getIntervalSeconds() : float
    {
        // NOT STARTED
        if (empty($this->start))
            return 0;
        // NOT STOPPED
        if (empty($this->stop))
            return ($this->stop - self::microtime_float());

        return $interval = $this->stop - $this->start;
    }

    /**
     * FOR MORE INFO SEE http://us.php.net/microtime
     *
     * @return float
     */
    private static function microtime_float() : float
    {
        list($usec, $sec) = explode(" ", microtime());

        return ((float)$usec + (float)$sec);
    }
}
mils
quelle
1

Hier ist mein Skript zum Messen der durchschnittlichen Zeit

<?php

$times = [];
$nbrOfLoops = 4;
for ($i = 0; $i < $nbrOfLoops; ++$i) {
    $start = microtime(true);
    sleep(1);
    $times[] = microtime(true) - $start;
}

echo 'Average: ' . (array_sum($times) / count($times)) . 'seconds';
William Desportes
quelle
0

Sie können die Ausführungszeit in Sekunden mit einer einzigen Funktion ermitteln.

// ampersand is important thing here
function microSec( & $ms ) {
    if (\floatval( $ms ) == 0) {
        $ms = microtime( true );
    }
    else {
        $originalMs = $ms;
        $ms = 0;
        return microtime( true ) - $originalMs;
    }
}

// you don't have to define $ms variable. just function needs
// it to calculate the difference.
microSec($ms);
sleep(10);
echo microSec($ms) . " seconds"; // 10 seconds

for( $i = 0; $i < 10; $i++) {
    // you can use same variable everytime without assign a value
    microSec($ms);
    sleep(1);
    echo microSec($ms) . " seconds"; // 1 second
}

for( $i = 0; $i < 10; $i++) {
    // also you can use temp or useless variables
    microSec($xyzabc);
    sleep(1);
    echo microSec($xyzabc) . " seconds"; // 1 second
}
Kodmanyagha
quelle