Maneira precisa de medir o tempo de execução de scripts php

270

Quero saber quantos milissegundos um loop for PHP leva para executar.

Conheço a estrutura de um algoritmo genérico, mas não faço ideia de como implementá-lo no 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
fonte
Você pode mexer com declarações de microtime () se precisar disso na produção, mas se for apenas para teste, use o criador de perfil do xdebug, por exemplo. Nenhum código bagunçado é uma vantagem real.
precisa saber é o seguinte

Respostas:

525

Você pode usar a microtimefunção para isso. A partir da documentação :

microtime - Retorne o timestamp atual do Unix com microssegundos


Se get_as_floatestiver definido como TRUE, microtime()retornará um ponto flutuante, que representa o tempo atual em segundos desde que a época do Unix é precisa até o microssegundo mais próximo.

Exemplo de uso:

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

}
$time_elapsed_secs = microtime(true) - $start;
Tim Cooper
fonte
36
Você precisa microtime(true)se deseja fazer cálculos com o valor de retorno.
Loneomeday
7
Eu sei que isso é tarde demais (quase 4 anos), mas como um comentário ... usar esses cálculos (com o parâmetro get_as_floatas true) fornecerá resultados em segundos , de acordo com a documentação do PHP.
Alejandro Iván
6
@patrick e é isso que eu disse: se get_as_floaté true, microtime()retorna o valor que representa os segundos ...
Alejandro Iván
2
Embora esta seja uma publicação muito antiga, devemos nos referir ao fato de que o float retornado contém os microssegundos ... A melhor solução é multiplicar por 1000 ... consulte stackoverflow.com/questions/3656713/… como exemplo. .
irritado 84
1
Esta resposta está desatualizada. Hoje em dia a melhor maneira de tempo relatório de execução de script é uma única linha no final do seu código: $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]; (Mais informação em uma resposta abaixo .)
ashleedawg
84

Você pode usar microtime(true)com as seguintes maneiras:

Coloque isso no início do seu arquivo php:

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

// seu código de script vai aqui

// do something

Coloque isso no final do seu arquivo 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';

Ele produzirá o resultado minutes.

Aditya P Bhatt
fonte
72

Você pode usar a REQUEST_TIMEpartir da $_SERVERmatriz superglobal. A partir da documentação :

REQUEST_TIME
O registro de data e hora do início da solicitação. (Disponível desde o PHP 5.1.0.)

REQUEST_TIME_FLOAT
O registro de data e hora do início da solicitação, com precisão de microssegundos . (Disponível desde o PHP 5.4.0.)

Dessa forma, você não precisa salvar um carimbo de data / hora no início do seu script. Você pode simplesmente fazer:

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

Aqui, $timeconteria o tempo decorrido desde o início do script em segundos, com precisão de microssegundos (por exemplo, 1.341por 1 segundo e 341 microssegundos)


Mais informações:

Documentação do PHP : $_SERVERvariáveis e microtimefunção

Iwazaru
fonte
Isso é útil para saber. Então você pode usar:$start = $_SERVER["REQUEST_TIME_FLOAT"]; $myscript = microtime(true); $bootstrap = $myscript - $start; ...do stuff ...; $myscripttime = microtime(true) - $myscript;
pspahn
1
Bem, o ponto principal de usar isso é que você pode simplesmente fazer: $myscripttime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];no final do seu script sem precisar salvar um carimbo de data / hora no início.
Iwazaru
1
De acordo com a documentação vinculada, $timeconterá a diferença em segundos , não em microssegundos .
Wim Deblauwe
4
@WimDeblauwe Para esclarecer, sim, o resultado é em segundos. Mas com precisão de microssegundos . por exemplo, 1.1equivale a 1 segundo + 100 microssegundos.
Chris Harrison
1
Esta é a melhor maneira de medir o tempo de resposta #
Mike Aron
27

Crie o arquivo 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";
    }
}

Do que no começo do seu script, depois de <?phpescreverinclude 'loadtime.php'; $loadtime=new loadTime();

Quando a página é carregada no final, será escrito "Carregado em x segundos"

Solo Omsarashvili
fonte
5
Arrumado! Mas se você não destruir explicitamente o seu objeto, a saída será exibida após a </html>tag de fechamento inválida
Dmitry Pashkevich
@gondo Não, serão segundos (com microssegundos expressos como valores decimais de sceconds) #
FrancescoMM
19
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
    // do something
}
$total = microtime(true) - $start;
echo $total;
Dvir Azulay
fonte
7

Veja microtime () .

patapizza
fonte
7

Aqui está uma função que cronometra a execução de qualquer parte do código PHP, assim como o módulo timeit do Python: https://gist.github.com/flaviovs/35aab0e85852e548a60a

Como usá-lo:

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

Disclaimer: Eu sou o autor deste Gist

EDIT: timeit agora é um projeto separado e independente em https://github.com/flaviovs/timeit

flaviovs
fonte
5

Você tem a idéia certa, exceto que um tempo mais preciso está disponível com a função microtime () .

Se o que estiver dentro do loop for rápido, é possível que o tempo decorrido aparente seja zero. Nesse caso, envolva outro loop no código e chame-o repetidamente. Certifique-se de dividir a diferença pelo número de iterações para obter uma vez por vez. Criei um código de perfil que exigia 10.000.000 de iterações para obter resultados consistentes e confiáveis ​​de tempo.

Wallyk
fonte
3

Eu pensei em compartilhar a função que eu criei. Espero que você possa economizar tempo.

Ele foi originalmente usado para rastrear o tempo de um script baseado em texto, portanto, a saída está no formato de texto. Mas você pode modificá-lo facilmente para HTML, se preferir.

Ele fará todos os cálculos para você por quanto tempo foi gasto desde o início do script e em cada etapa. Ele formata toda a saída com 3 casas decimais de precisão. (Até milissegundos.)

Depois de copiá-lo para a parte superior do seu script, tudo o que você faz é colocar as chamadas da função recordTime após cada peça que você desejar.

Copie isso para o topo do seu arquivo 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 acompanhar o tempo que passa, basta:

recordTime("What We Just Did")

Por exemplo:

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

Dá saída assim:

//     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 isso ajude alguém!

azoundria
fonte
2

Aqui está um método muito simples e curto

<?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
fonte
Acho ur ur algo que eu testei esse código quando eu postei resposta
Deepak Kumar
var_dump (microtime (true)); // float (1283846202.89) é isso que quando você usa microtime true
Deepak Kumar
Você também pode usar float no tempo total
Deepak Kumar
2

se você deseja exibir esse tempo em 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();
Eugene Kaurov
fonte
1

Aqui está uma implementação que retorna segundos fracionários (ou seja, 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);
    }
}
mils
fonte
1

Aqui está o meu script para medir o tempo médio

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

Você pode encontrar o tempo de execução em segundo com uma única função.

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