Modo preciso per misurare i tempi di esecuzione degli script php


270

Voglio sapere quanti millisecondi ci vuole per eseguire un PHP for-loop.

Conosco la struttura di un algoritmo generico, ma non ho idea di come implementarlo in 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

Puoi giocherellare con una manciata di istruzioni microtime () se ne hai bisogno in produzione, ma se è solo per i test, usa il profiler di xdebug per esempio. Nessun codice disordinato è un vero vantaggio.
Wrikken,

Risposte:


525

È possibile utilizzare la microtimefunzione per questo. Dalla documentazione :

microtime - Restituisce il timestamp Unix corrente con microsecondi


Se get_as_floatè impostato su TRUE, quindi microtime()restituisce un valore a virgola mobile, che rappresenta l'ora corrente in secondi dall'epoca di Unix accurata al microsecondo più vicino.

Esempio di utilizzo:

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

}
$time_elapsed_secs = microtime(true) - $start;

36
È necessario microtime(true)se si desidera eseguire calcoli con il valore restituito.
lunedì

7
So che questo è troppo tardi (quasi 4 anni), ma come commento ... l'uso di questi calcoli (con il parametro get_as_floatas true) ti darà risultati in pochi secondi , secondo la documentazione di PHP.
Alejandro Iván,

6
@patrick ed è quello che ho detto: se lo get_as_floatè true, microtime()restituisce il valore che rappresenta i secondi ...
Alejandro Iván,

2
Anche se questo è un post molto vecchio, dovremmo fare riferimento al fatto che il float restituito contiene i microsecondi ... La migliore soluzione è a volte questo per 1000 ... vedi stackoverflow.com/questions/3656713/… come esempio. .
Angry 84

1
Questa risposta non è aggiornata. Oggi il modo migliore per segnalare il tempo di esecuzione dello script è una singola riga alla fine del codice: $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]; (Maggiori informazioni in una risposta di seguito .)
ashleedawg

84

Puoi usare microtime(true) con le seguenti maniere:

Metti questo all'inizio del tuo file php:

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

// il codice dello script va qui

// do something

Metti questo alla fine del tuo file 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';

Verrà generato il risultato minutes.


72

È possibile utilizzare REQUEST_TIMEdalla $_SERVERmatrice superglobale. Dalla documentazione :

REQUEST_TIME
Il timestamp dell'inizio della richiesta. (Disponibile da PHP 5.1.0.)

REQUEST_TIME_FLOAT
Il timestamp dell'inizio della richiesta, con precisione in microsecondi . (Disponibile da PHP 5.4.0.)

In questo modo non è necessario salvare un timestamp all'inizio dello script. Puoi semplicemente fare:

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

Qui, $timeconterrebbe il tempo trascorso dall'inizio dello script in secondi, con precisione in microsecondi (ad es. 1.341Per 1 secondo e 341 microsecondi)


Ulteriori informazioni:

Documentazione PHP : $_SERVERvariabili e microtimefunzione


È utile saperlo. Quindi potresti usare:$start = $_SERVER["REQUEST_TIME_FLOAT"]; $myscript = microtime(true); $bootstrap = $myscript - $start; ...do stuff ...; $myscripttime = microtime(true) - $myscript;
pspahn

1
Bene a tutto punto sull'uso di questo è che potresti semplicemente fare: $myscripttime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];alla fine del tuo script senza dover salvare un timestamp all'inizio.
Iwazaru,

1
Secondo la documentazione collegata, $timeconterrà la differenza in secondi , non in microsecondi .
Wim Deblauwe,

4
@WimDeblauwe Per chiarire, sì, il risultato è in secondi. Ma con precisione al microsecondo . eg 1.1equivale a 1 secondo + 100 microsecondi.
Chris Harrison,

1
Questo è il modo migliore per misurare il tempo di risposta
Mike Aron,

27

Crea il file 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";
    }
}

Che all'inizio della tua sceneggiatura, dopo aver <?phpscrittoinclude 'loadtime.php'; $loadtime=new loadTime();

Quando la pagina viene caricata alla fine, verrà scritto "Caricato in x secondi"


5
! Neat Ma se non distruggi esplicitamente il tuo oggetto, l'output apparirà dopo il </html>tag di chiusura che non è valido
Dmitry Pashkevich

@gondo No, saranno secondi (con microsecondi espressi come valori decimali di scecondi)
FrancescoMM,

19
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
    // do something
}
$total = microtime(true) - $start;
echo $total;


7

Ecco una funzione che moltiplica l'esecuzione di qualsiasi pezzo di codice PHP, proprio come fa il modulo timeit di Python: https://gist.github.com/flaviovs/35aab0e85852e548a60a

Come usarlo:

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

Risultato:

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

Disclaimer: sono l'autore di questo Gist

EDIT: timeit è ora un progetto separato e autonomo su https://github.com/flaviovs/timeit


5

Hai la giusta idea, tranne che un tempo più preciso è disponibile con il microtime () .

Se ciò che è all'interno del loop è veloce, è possibile che il tempo trascorso apparente sia zero. In tal caso, avvolgere un altro ciclo attorno al codice e chiamarlo ripetutamente. Assicurati di dividere la differenza per il numero di iterazioni per ottenere una volta per volta. Ho un codice profilato che ha richiesto 10.000.000 di iterazioni per ottenere risultati di temporizzazione coerenti e affidabili.


3

Ho pensato di condividere la funzione che ho messo insieme. Spero che possa farti risparmiare tempo.

È stato originariamente utilizzato per tenere traccia dei tempi di uno script basato su testo, quindi l'output è in formato testo. Ma puoi facilmente modificarlo in HTML se preferisci.

Farà tutti i calcoli per te per quanto tempo è stato trascorso dall'inizio dello script e in ogni passaggio. Formatta tutto l'output con 3 decimali di precisione. (Fino a millisecondi.)

Una volta copiato nella parte superiore del tuo script, tutto ciò che fai è inserire le chiamate della funzione recordTime dopo ogni pezzo che vuoi cronometrare.

Copia questo nella parte superiore del file di script:

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

Per tenere traccia del tempo che passa, basta fare:

recordTime("What We Just Did")

Per esempio:

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

Fornisce un output in questo modo:

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

Spero che questo aiuti qualcuno!


2

Ecco un metodo molto semplice e breve

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

Penso che manchi qualcosa che ho provato quel codice quando ho pubblicato la risposta
Deepak Kumar

var_dump (microtime (true)); // float (1283846202.89) ecco cosa succede quando si usa microtime true
Deepak Kumar

Puoi anche usare il float in totale tempo
Deepak Kumar

2

se ti piace visualizzare quel tempo in secondi:

<?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();

1

Ecco un'implementazione che restituisce secondi frazionari (ovvero 1,332 secondi)

/**
 * 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);
    }
}

1

Ecco la mia sceneggiatura per misurare il tempo medio

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

0

Puoi trovare il tempo di esecuzione in secondi con una singola funzione.

// 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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.