Un moyen précis de mesurer les temps d'exécution des scripts php

270

Je veux savoir combien de millisecondes une boucle PHP prend pour s'exécuter.

Je connais la structure d'un algorithme générique, mais je ne sais pas comment l'implémenter 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
DomingoSL
la source
Vous pouvez jouer avec des bandes d'instructions microtime () si vous en avez besoin en production, mais si c'est juste pour les tests, utilisez simplement le profileur de xdebug par exemple. Aucun code désordonné n'est un vrai plus.
Wrikken

Réponses:

525

Vous pouvez utiliser la microtimefonction pour cela. De la documentation :

microtime - Retourne l'horodatage Unix actuel avec microsecondes


Si get_as_floatest défini sur TRUE, microtime()renvoie un flottant, qui représente le temps actuel en secondes depuis l'époque Unix précis à la microseconde près.

Exemple d'utilisation:

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

}
$time_elapsed_secs = microtime(true) - $start;
Tim Cooper
la source
36
Vous avez besoin microtime(true)si vous voulez faire des calculs avec la valeur de retour.
lonesomeday
7
Je sais que c'est waaaaaay trop tard (près de 4 ans), mais en tant que commentaire ... l'utilisation de ces calculs (avec le paramètre get_as_floatas true) vous donnera des résultats en quelques secondes , selon la documentation PHP.
Alejandro Iván
6
@patrick et c'est ce que j'ai dit: si get_as_floatc'est le cas true, microtime()retourne la valeur représentant les secondes ...
Alejandro Iván
2
Bien qu'il s'agisse d'un article très ancien, nous devons nous référer au fait que le flottant renvoyé contient les microsecondes ... La meilleure solution consiste à multiplier par 1000 ... voir stackoverflow.com/questions/3656713/… comme exemple. .
Angry 84
1
Cette réponse est obsolète. De nos jours, la meilleure façon de signaler le temps d'exécution d'un script est une seule ligne à la fin de votre code: $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]; (Plus d'informations dans une réponse ci-dessous .)
ashleedawg
84

Vous pouvez utiliser microtime(true)les manières suivantes:

Mettez ceci au début de votre fichier php:

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

// votre code de script va ici

// do something

Mettez ceci à la fin de votre fichier 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';

Il en résultera votre résultat minutes.

Aditya P Bhatt
la source
72

Vous pouvez utiliser à REQUEST_TIMEpartir du $_SERVERtableau superglobal. De la documentation :

REQUEST_TIME
Horodatage du début de la demande. (Disponible depuis PHP 5.1.0.)

REQUEST_TIME_FLOAT
Horodatage du début de la demande, avec une précision en microsecondes . (Disponible depuis PHP 5.4.0.)

De cette façon, vous n'avez pas besoin d'enregistrer un horodatage au début de votre script. Vous pouvez simplement faire:

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

Ici, $timecontiendrait le temps écoulé depuis le début du script en secondes, avec une précision en microsecondes (par exemple, 1.341pendant 1 seconde et 341 microsecondes)


Plus d'informations:

Documentation PHP : $_SERVERvariables et microtimefonction

Iwazaru
la source
C'est pratique à savoir. Vous pouvez donc utiliser:$start = $_SERVER["REQUEST_TIME_FLOAT"]; $myscript = microtime(true); $bootstrap = $myscript - $start; ...do stuff ...; $myscripttime = microtime(true) - $myscript;
pspahn le
1
Eh bien, l'essentiel de l'utilisation de ceci est que vous pouvez simplement le faire: $myscripttime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];à la fin de votre script sans avoir à enregistrer un horodatage au début.
Iwazaru
1
Selon la documentation liée, $timecontiendra la différence en secondes , pas en microsecondes .
Wim Deblauwe
4
@WimDeblauwe Pour clarifier, oui le résultat est en quelques secondes. Mais avec une précision en microsecondes . par exemple 1.1équivaut à 1 seconde + 100 microsecondes.
Chris Harrison
1
C'est le meilleur moyen de mesurer le temps de réponse
Mike Aron
27

Créez le fichier 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";
    }
}

Au début de votre script, après avoir <?phpécritinclude 'loadtime.php'; $loadtime=new loadTime();

Lorsque la page est chargée à la fin, il sera écrit "Chargé en x secondes"

Solo Omsarashvili
la source
5
Soigné! Mais si vous ne détruisez pas explicitement votre objet, la sortie apparaîtra après la </html>balise de fermeture qui n'est pas valide
Dmitry Pashkevich
@gondo Non, ce sera quelques secondes (avec les microsecondes exprimées en valeurs décimales de secondes)
FrancescoMM
19
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
    // do something
}
$total = microtime(true) - $start;
echo $total;
Dvir Azulay
la source
7

Voici une fonction qui chronomètre l'exécution de n'importe quel morceau de code PHP, un peu comme le module timeit de Python: https://gist.github.com/flaviovs/35aab0e85852e548a60a

Comment l'utiliser:

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

Résultat:

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

Avertissement: je suis l'auteur de ce Gist

EDIT: timeit est maintenant un projet séparé et autonome sur https://github.com/flaviovs/timeit

flaviovs
la source
5

Vous avez la bonne idée, sauf qu'un timing plus précis est disponible avec le microtime () .

Si ce qui se trouve à l'intérieur de la boucle est rapide, il est possible que le temps écoulé apparent soit nul. Si c'est le cas, enroulez une autre boucle autour du code et appelez-le à plusieurs reprises. Assurez-vous de diviser la différence par le nombre d'itérations pour obtenir une fois par fois. J'ai profilé du code qui a nécessité 10 000 000 d'itérations pour obtenir des résultats de synchronisation cohérents et fiables.

wallyk
la source
3

Je pensais partager la fonction que j'avais mise en place. J'espère que cela peut vous faire gagner du temps.

Il était à l'origine utilisé pour suivre le timing d'un script texte, donc la sortie est sous forme de texte. Mais vous pouvez facilement le modifier en HTML si vous préférez.

Il fera tous les calculs pour vous pour combien de temps a été passé depuis le début du script et à chaque étape. Il formate toute la sortie avec 3 décimales de précision. (Jusqu'à quelques millisecondes.)

Une fois que vous l'avez copié en haut de votre script, il vous suffit de placer les appels de la fonction recordTime après chaque morceau que vous souhaitez chronométrer.

Copiez ceci en haut de votre fichier 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;
}

Pour suivre le temps qui passe, faites simplement:

recordTime("What We Just Did")

Par exemple:

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

Donne une sortie comme ceci:

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

J'espère que cela aide quelqu'un!

azoundria
la source
2

Voici une méthode très simple et courte

<?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
la source
Je pense que vous avez manqué quelque chose que j'ai testé ce code lorsque j'ai posté une réponse
Deepak Kumar
var_dump (microtime (vrai)); // float (1283846202.89) c'est ce qui se passe lorsque vous utilisez microtime true
Deepak Kumar
Vous pouvez également utiliser float en temps total
Deepak Kumar
2

si vous souhaitez afficher ce temps en secondes:

<?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
la source
1

Voici une implémentation qui retourne des fractions de seconde (soit 1,321 seconde)

/**
 * 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
la source
1

Voici mon script pour mesurer le temps moyen

<?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
la source
0

Vous pouvez trouver le temps d'exécution en seconde avec une seule fonction.

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