Dokładny sposób pomiaru czasu wykonania skryptów php

270

Chcę wiedzieć, ile milisekund zajmuje wykonanie pętli for PHP.

Znam strukturę ogólnego algorytmu, ale nie mam pojęcia, jak zaimplementować go w PHP:

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
źródło
Możesz bawić się pokosami instrukcji microtime (), jeśli potrzebujesz tego podczas produkcji, ale jeśli to tylko do testowania, po prostu użyj na przykład profilera xdebug . Brak niechlujnego kodu to prawdziwy plus.
Wrikken,

Odpowiedzi:

525

Możesz do tego użyć microtimefunkcji. Z dokumentacji :

microtime - Zwraca aktualny znacznik czasu Unix z mikrosekundami


Jeśli get_as_floatustawione na TRUE, to microtime()zwraca liczbę zmiennoprzecinkową, która reprezentuje aktualny czas w sekundach od epoki Uniksa z dokładnością do najbliższej mikrosekundy.

Przykładowe użycie:

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

}
$time_elapsed_secs = microtime(true) - $start;
Tim Cooper
źródło
36
Potrzebujesz, microtime(true)jeśli chcesz wykonać obliczenia z wartością zwracaną.
lonesomeday
7
Wiem, że to jest za późno (prawie 4 lata), ale jako komentarz ... użycie tych obliczeń (z parametrem get_as_floatas true) da wyniki w kilka sekund , zgodnie z dokumentacją PHP.
Alejandro Iván
6
@patrick i tak powiedziałem: jeśli get_as_floattak true, microtime()zwraca wartość reprezentującą sekundy ...
Alejandro Iván
2
Chociaż jest to bardzo stary post, powinniśmy odnieść się do faktu, że zwrócony float zawiera mikrosekundy ... Najlepszym rozwiązaniem jest pomnożenie tego o 1000 ... patrz przykład stackoverflow.com/questions/3656713/ ... ,
Angry 84
1
Ta odpowiedź jest nieaktualna. Obecnie najlepszym sposobem zgłaszania czasu wykonania skryptu jest pojedynczy wiersz na końcu kodu: $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]; (Więcej informacji w odpowiedzi poniżej .)
ashleedawg
84

Możesz używać microtime(true)następujących sposobów:

Umieść to na początku pliku php:

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

// Twój kod skryptu jest tutaj

// do something

Umieść to na końcu pliku php:

// 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';

To da ci wynik minutes.

Aditya P Bhatt
źródło
72

Możesz używać REQUEST_TIMEz $_SERVERtablicy superglobalnej. Z dokumentacji :

REQUEST_TIME
Znacznik czasu rozpoczęcia żądania. (Dostępne od PHP 5.1.0.)

REQUEST_TIME_FLOAT
Znacznik czasu początku żądania z dokładnością do mikrosekundy . (Dostępne od PHP 5.4.0.)

W ten sposób nie musisz zapisywać znacznika czasu na początku skryptu. Możesz po prostu zrobić:

<?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";
?>

Tutaj $timezawierałby czas, jaki upłynął od rozpoczęcia skryptu, w sekundach, z dokładnością do mikrosekund (np. 1.341Przez 1 sekundę i 341 mikrosekund)


Więcej informacji:

Dokumentacja PHP : $_SERVERzmienne i microtimefunkcja

Iwazaru
źródło
Warto to wiedzieć. Możesz użyć:$start = $_SERVER["REQUEST_TIME_FLOAT"]; $myscript = microtime(true); $bootstrap = $myscript - $start; ...do stuff ...; $myscripttime = microtime(true) - $myscript;
pspahn
1
Chodzi o to, że możesz to zrobić: $myscripttime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];na końcu skryptu bez konieczności zapisywania znacznika czasu na początku.
Iwazaru,
1
Według powiązanej dokumentacji $timeróżnica będzie zawierać się w sekundach , a nie w mikrosekundach .
Wim Deblauwe
4
@WimDeblauwe Aby wyjaśnić, tak, wynik jest w sekundach. Ale z mikrosekundową precyzją . np. 1.1odpowiada 1 sekundzie + 100 mikrosekund.
Chris Harrison
1
To najlepszy sposób, aby zmierzyć czas reakcji
Mike Aron,
27

Utwórz plik 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";
    }
}

Niż na początku skryptu, po <?phpnapisaniuinclude 'loadtime.php'; $loadtime=new loadTime();

Po załadowaniu strony na końcu zostanie napisane „Załadowano za x sekund”

Solo Omsarashvili
źródło
5
Schludny! Ale jeśli nie zniszczysz bezpośrednio swojego obiektu, wynik pojawi się po </html>tagu zamykającym, który jest nieprawidłowy
Dmitrij Paszkiewicz
@gondo Nie, to będą sekundy (z mikrosekundami wyrażonymi jako wartości dziesiętne sceconds)
FrancescoMM,
19
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
    // do something
}
$total = microtime(true) - $start;
echo $total;
Dvir Azulay
źródło
7

Oto funkcja, która wykonuje wykonanie dowolnego fragmentu kodu PHP, podobnie jak moduł timeit Pythona: https://gist.github.com/flaviovs/35aab0e85852e548a60a

Jak tego użyć:

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

Wynik:

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

Uwaga: Jestem autorem tej treści

EDYCJA: timeit jest teraz osobnym, niezależnym projektem na https://github.com/flaviovs/timeit

Flaviovs
źródło
5

Masz dobry pomysł, z wyjątkiem tego, że dzięki funkcji microtime () można uzyskać bardziej precyzyjny czas .

Jeśli zawartość pętli jest szybka, możliwe, że pozorny czas, który upłynął, wyniesie zero. Jeśli tak, owiń kolejną pętlę wokół kodu i wywołuj go wielokrotnie. Pamiętaj, aby podzielić różnicę przez liczbę iteracji, aby uzyskać jeden raz. Mam profilowany kod, który wymagał 10 000 000 iteracji, aby uzyskać spójne, wiarygodne wyniki czasowe.

wallyk
źródło
3

Myślałem, że podzielę się funkcją, którą razem stworzyłem. Mamy nadzieję, że pozwoli Ci to zaoszczędzić czas.

Pierwotnie był używany do śledzenia czasu skryptu tekstowego, więc wynik jest w formie tekstowej. Ale jeśli chcesz, możesz łatwo zmodyfikować go do formatu HTML.

Wykona wszystkie obliczenia dla ciebie, ile czasu spędziłeś od początku skryptu i na każdym kroku. Formatuje wszystkie dane wyjściowe z dokładnością do 3 miejsc po przecinku. (Do milisekund).

Po skopiowaniu go na początek skryptu wystarczy umieścić wywołania funkcji recordTime po każdym utworze, który ma zostać określony.

Skopiuj to na górę pliku skryptu:

$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;
}

Aby śledzić upływający czas, po prostu wykonaj:

recordTime("What We Just Did")

Na przykład:

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)
}

Daje dane wyjściowe w następujący sposób:

//     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

Mam nadzieję, że to komuś pomoże!

azoundria
źródło
2

Oto bardzo prosta i krótka metoda

<?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
źródło
Wydaje mi się, że brakuje Ci czegoś, co przetestowałem, gdy opublikowałem odpowiedź
Deepak Kumar
var_dump (microtime (true)); // float (1283846202.89) to jest to, kiedy używasz mikrotime true
Deepak Kumar
Możesz także użyć pływaka w czasie całkowitym
Deepak Kumar
2

jeśli chcesz wyświetlić ten czas w sekundach:

<?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
źródło
1

Oto implementacja, która zwraca ułamek sekundy (tj. 1,321 sekundy)

/**
 * 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
źródło
1

Oto mój skrypt do pomiaru średniego czasu

<?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
źródło
0

Możesz znaleźć czas wykonania w sekundę za pomocą jednej funkcji.

// 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
źródło