Точный способ измерения времени выполнения сценариев php

270

Я хочу знать, сколько миллисекунд требуется для цикла PHP for.

Я знаю структуру универсального алгоритма, но не знаю, как реализовать его в 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
источник
Вы можете возиться с множеством операторов microtime (), если вам это нужно в работе, но если это только для тестирования, просто используйте , например , профилировщик xdebug. Никакой грязный код не является настоящим плюсом.
Wrikken

Ответы:

525

Вы можете использовать microtimeфункцию для этого. Из документации :

microtime - Возвращает текущую метку времени Unix с микросекундами.


Если get_as_floatустановлено значение TRUE, то microtime()возвращает значение с плавающей запятой, которое представляет текущее время в секундах с начала эпохи Unix с точностью до ближайшей микросекунды.

Пример использования:

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

}
$time_elapsed_secs = microtime(true) - $start;
Тим Купер
источник
36
Вам нужно, microtime(true)если вы хотите сделать вычисления с возвращаемым значением.
одинокий
7
Я знаю, что это слишком поздно (почти 4 года), но в качестве комментария ... использование этих вычислений (с параметром get_as_floatas true) даст вам результаты в считанные секунды , согласно документации PHP.
Алехандро Иван
6
@patrick, и вот что я сказал: если get_as_floatесть true, microtime()возвращает значение, представляющее секунды ...
Алехандро Иван
2
Хотя это очень старая запись, мы должны сослаться на тот факт, что возвращаемое значение с плавающей запятой содержит микросекунды ... Лучшее решение - умножить это на 1000 ... см. В качестве примера stackoverflow.com/questions/3656713/… .
Сердитый 84
1
Этот ответ устарел. В настоящее время лучший способ сообщить о времени выполнения скрипта - это одна строка в конце вашего кода: $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]; (Подробнее см . В ответе ниже .)
ashleedawg
84

Вы можете использовать microtime(true)следующие способы:

Поместите это в начало вашего php файла:

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

// ваш код скрипта идет сюда

// do something

Поместите это в конец вашего 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';

Это выведет ваш результат в minutes.

Адитья П Бхатт
источник
72

Вы можете использовать REQUEST_TIMEиз $_SERVERсуперглобального массива. Из документации :

REQUEST_TIME
Отметка времени начала запроса. (Доступно с PHP 5.1.0.)

REQUEST_TIME_FLOAT
Отметка времени начала запроса с точностью до микросекунды . (Доступно с PHP 5.4.0.)

Таким образом, вам не нужно сохранять временную метку в начале вашего скрипта. Вы можете просто сделать:

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

Здесь $timeбудет содержать время, прошедшее с момента запуска скрипта в секундах, с точностью до микросекунд (например, 1.341за 1 секунду и 341 микросекунду)


Больше информации:

PHP документация : $_SERVERпеременные и microtimeфункции

Iwazaru
источник
Это удобно знать. Таким образом, вы можете использовать:$start = $_SERVER["REQUEST_TIME_FLOAT"]; $myscript = microtime(true); $bootstrap = $myscript - $start; ...do stuff ...; $myscripttime = microtime(true) - $myscript;
pspahn
1
В целом, суть использования этого заключается в том, что вы можете просто сделать: $myscripttime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];в конце вашего сценария, не сохраняя временную метку в начале.
Ивазару
1
Согласно связанной документации, $timeбудет содержать разницу в секундах , а не в микросекундах .
Вим Deblauwe
4
@WimDeblauwe Чтобы уточнить, да, результат в секундах. Но с точностью до микросекунды . например, 1.1равняется 1 секунде + 100 микросекундам.
Крис Харрисон
1
Это лучший способ измерить время отклика
Майк Арон
27

Создать файл 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";
    }
}

Чем в начале вашего сценария, после <?phpзаписиinclude 'loadtime.php'; $loadtime=new loadTime();

Когда страница будет загружена в конце, будет написано «Загружен за x секунд»

Соло Омсарашвили
источник
5
Ухоженная! Но если вы явно не уничтожите свой объект, вывод будет появляться после закрывающего </html>тега, который недопустим
Дмитрий Пашкевич
@gondo Нет, это будут секунды (с микросекундами, выраженными в виде десятичных значений Sceconds)
FrancescoMM
19
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
    // do something
}
$total = microtime(true) - $start;
echo $total;
Двир Азулай
источник
7

Вот функция, которая измеряет время выполнения любого фрагмента кода PHP, так же, как это делает модуль Python timeit: https://gist.github.com/flaviovs/35aab0e85852e548a60a

Как это использовать:

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

Результат:

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

Отказ от ответственности: я автор этого Gist

РЕДАКТИРОВАТЬ: timeit теперь является отдельным, автономным проектом по адресу https://github.com/flaviovs/timeit

flaviovs
источник
5

У вас правильная идея, за исключением того, что более точная синхронизация доступна с функцией microtime () .

Если то, что находится внутри цикла, быстро, возможно, что истекшее время будет равно нулю. Если это так, оберните другой цикл вокруг кода и вызывайте его повторно. Обязательно разделите разницу на количество итераций, чтобы получить время за один раз. У меня есть профилированный код, который требует 10 000 000 итераций для получения согласованных и надежных результатов синхронизации.

wallyk
источник
3

Я думал, что разделю функцию, которую я собрал. Надеюсь, это поможет вам сэкономить время.

Первоначально он использовался для отслеживания времени выполнения текстового сценария, поэтому вывод осуществляется в текстовой форме. Но вы можете легко изменить его на HTML, если хотите.

Он сделает все расчеты за то, сколько времени было потрачено с момента запуска скрипта и на каждом шаге. Он форматирует весь вывод с точностью до 3 десятичных знаков. (До миллисекунд.)

После того, как вы скопируете его в начало вашего скрипта, все, что вам нужно сделать, это поместить вызовы функции recordTime после каждого фрагмента, который вы хотите установить по времени.

Скопируйте это в начало вашего файла сценария:

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

Чтобы отслеживать время, которое вы проходите, просто выполните:

recordTime("What We Just Did")

Например:

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

Дает вывод, как это:

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

Надеюсь, это поможет кому-то!

azoundria
источник
2

Вот очень простой и короткий метод

<?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
?>
Дипак Кумар
источник
Я думаю, что вы что-то упустили, я протестировал этот код, когда отправил ответ
Дипак Кумар
var_dump (микропоры (истина)); // float (1283846202.89) вот что, когда вы используете microtime true
Дипак Кумар
Вы также можете использовать плавание в общем времени
Дипак Кумар
2

если вы хотите отобразить это время в секундах:

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

Вот реализация, которая возвращает дробные секунды (т.е. 1.321 секунды)

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

Вот мой скрипт для измерения среднего времени

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

Вы можете найти время выполнения в секундах с помощью одной функции.

// 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
источник