Forma precisa de medir los tiempos de ejecución de scripts php


Quiero saber cuántos milisegundos tarda en ejecutarse un for-loop de PHP.

Conozco la estructura de un algoritmo genérico, pero no tengo idea de cómo implementarlo en 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
 203
php
Author: Eric Leschinski, 2011-06-06

12 answers

Puede utilizar el microtime función para esto. De la documentación :

microtime - Devuelve la marca de tiempo Unix actual con microsegundos


Si get_as_float se establece en TRUE, entonces microtime() devuelve un flotador, que representa la hora actual en segundos desde que el epoch de Unix es preciso al microsegundo más cercano.

Ejemplo de uso:

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

}
$time_elapsed_secs = microtime(true) - $start;
 390
Author: Tim Cooper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-11 14:52:41

Puedes usar microtime(true) con los siguientes modales:

Pon esto al principio de tu archivo php:

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

/ / su código de script va aquí

// do something

Pon esto al final de tu archivo 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';

Te dará como resultado minutes.

 72
Author: Aditya P Bhatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-20 13:58:13

Puedes usar REQUEST_TIME desde el array superglobal $_SERVER. De la documentación :

'REQUEST_TIME'
La marca de tiempo del inicio de la solicitud. Disponible desde PHP 5.1.0.

'REQUEST_TIME_FLOAT'
La marca de tiempo del inicio de la solicitud, con precisión de microsegundos. Disponible desde PHP 5.4.0.

De esta manera no necesita guardar una marca de tiempo al principio de su script. Simplemente puedes hacer:

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

Aquí, $time sería contiene el tiempo transcurrido desde el inicio del script en segundos, con precisión de microsegundos (ej. 1.341 durante 1 segundo y 341 microsegundos)

 61
Author: Iwazaru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-30 14:37:24

Crear el archivo 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";
    }
}

Que al principio de tu escritura, después de <?php escribir include 'loadtime.php'; $loadtime=new loadTime();

Cuando se carga la página al final se escribirá "Loaded in x seconds"

 24
Author: Solo Omsarashvili BBuLLeTT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-18 15:46:27
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
    // do something
}
$total = microtime(true) - $start;
echo $total;
 17
Author: Dvir Azulay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-05 21:29:16
 7
Author: patapizza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-05 21:28:09

Aquí hay una función que mide el tiempo de ejecución de cualquier pieza de código PHP, al igual que el módulo timeit de Python: https://gist.github.com/flaviovs/35aab0e85852e548a60a

Cómo usarlo:

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

Resultado:

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

Descargo de responsabilidad: Soy el autor de esta esencia

EDITAR: timeit es ahora un proyecto independiente y autónomo en https://github.com/flaviovs/timeit

 7
Author: flaviovs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-04 21:09:06

Tienes la idea correcta, excepto que un tiempo más preciso está disponible con la función microtime().

Si lo que está dentro del bucle es rápido, es posible que el tiempo transcurrido aparente sea cero. Si es así, envuelva otro bucle alrededor del código y llámelo repetidamente. Asegúrese de dividir la diferencia entre el número de iteraciones para obtener un tiempo por una vez. He perfilado el código que requiere 10.000.000 iteraciones para obtener resultados de sincronización consistentes y confiables.

 5
Author: wallyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-05 21:30:03

Pensé en compartir la función que organicé. Espero que pueda ahorrarte tiempo.

Originalmente se usó para rastrear el tiempo de un script basado en texto, por lo que la salida está en forma de texto. Pero puede modificarlo fácilmente a HTML si lo prefiere.

Hará todos los cálculos por usted para cuánto tiempo se ha gastado desde el inicio del script y en cada paso. Formatea toda la salida con 3 decimales de precisión. (Hasta milisegundos.)

Una vez que lo copia a la parte superior de su script, todo lo que hace es poner las llamadas a la función recordTime después de cada pieza que desea cronometrar.

Copie esto en la parte superior de su archivo de 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;
}

Para rastrear el tiempo que pasa, simplemente haga:

recordTime("What We Just Did")

Por ejemplo:

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

Da una salida como esta:

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

Espero que esto ayude a alguien!

 2
Author: azoundria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-24 19:11:09

Aquí es un método muy simple y corto

<?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
?>
 1
Author: Deepak Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-29 17:31:37

Aquí hay una implementación que devuelve segundos fraccionados (es decir, 1.321 segundos)

/**
 * 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
Author: mils,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-24 02:37:07

Si desea mostrar ese tiempo en segundos:

<?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();
 0
Author: Eugene Kaurov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-27 11:47:04