Web

Как я могу измерить скорость кода, написанного на PHP

Как я могу определить, какой класс из многих (которые все делают одну и ту же работу) выполняется быстрее? Существует ли программное обеспечение для измерения этого?

 

Ответ 1

У вас есть (по крайней мере) два решения:

  1. Довольно «наивное» — использовать microtime(true) до и после части кода, чтобы узнать, сколько времени прошло во время его выполнения.

  2. Это хорошее решение, если вы хотите сравнить пару инструкций, например, сравнить два типа функций лучше, если это будет сделано тысячи раз, чтобы убедиться, что любой «возмущающий элемент» усреднен.

Или использовать что-то вроде этого, например, если вы хотите узнать, сколько времени занимает сериализация массива:

$before = microtime(true);

for ($i=0 ; $i<100000 ; $i++) {

    serialize($list);

}

$after = microtime(true);

echo ($after-$before)/$i . " sec/serialize\n";

 Не идеально, но полезно и не требует много времени на настройку.

Другое решение, которое работает довольно хорошо, если вы хотите определить, какая функция занимает много времени во всем скрипте, это использовать:

  1. расширение Xdebug для генерации данных профилирования для скрипта;

  2. программное обеспечение, которое читает данные профилирования и представляет вам что-то удобочитаемое. Я знаю три из них:

  1. Webgrind ; веб-интерфейс; должен работать на любом сервере Apache+PHP;

  2. WinCacheGrind ; только на Windows;

  3. KCacheGrind ; возможно, только на Linux и Linux-подобных ОС; я предпочитаю именно его.

Чтобы получить файлы профилирования, вы должны установить и настроить Xdebug; посмотрите на страницу Profiling PHP Scripts в документации. Обычно я не включаю профайлер по умолчанию (он генерирует довольно большие файлы и замедляет работу), но использую возможность отправить параметр XDEBUG_PROFILE в качестве GET-данных, чтобы активировать профайлинг только для нужной мне страницы. Часть моего php.ini, связанная с профилированием, выглядит следующим образом:

xdebug.profiler_enable = 0                  ; Профилирование не включено по умолчанию

xdebug.profiler_enable_trigger = 1      ; Профилирование активируется при запросе параметром GET

xdebug.profiler_output_dir = /tmp/ouput_directory

xdebug.profiler_output_name = files_names

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

Обратите внимание, что Xdebug считает процессорное время, затраченное PHP; когда PHP ожидает ответа от базы данных (например), он не работает, а только ждет. Поэтому Xdebug будет считать, что запрос к БД не занимает много времени! Это должно быть профилировано на SQL-сервере, а не на PHP.

 

Ответ 2

Я сделал простой класс синхронизации, возможно, он будет кому-то полезен:

class TimingHelper {

    private $start;

    public function __construct() {

        $this->start = microtime(true);

    }

 

    public function start() {

        $this->start = microtime(true);

    }

 

    public function segs() {

        return microtime(true) - $this->start;

    }

 

    public function time() {

        $segs = $this->segs();

        $days = floor($segs / 86400);

        $segs -= $days * 86400;

        $hours = floor($segs / 3600);

        $segs -= $hours * 3600;

        $mins = floor($segs / 60);

        $segs -= $mins * 60;

        $microsegs = ($segs - floor($segs)) * 1000;

        $segs = floor($segs);

        return 

            (empty($days) ? "" : $days . "d ") . 

            (empty($hours) ? "" : $hours . "h ") . 

            (empty($mins) ? "" : $mins . "m ") . 

            $segs . "s " .

            $microsegs . "ms";

    }

}

 Использование:

$th = new TimingHelper();

<...измеряемый код...>

echo $th->time();

$th->start();// если это тот случай.

<...измеряемый код...>

echo $th->time();

// результат: 4d 17h 34m 57s 0.00095367431640625мс

 

 Ответ 3

Вот прямой ответ на ваш вопрос: есть ли программа для измерения этого?

Да, есть. Я удивляюсь, почему никто еще не упомянул об этом. Хотя ответы, предложенные выше, подходят для быстрой проверки, они не масштабируются в долгосрочной перспективе или для более крупного проекта. Почему бы не использовать инструменты мониторинга производительности приложений (APM), которые созданы именно для этого и многого другого. Посмотрите на NewRelic, AppDynamics, Ruxit (все они имеют бесплатную версию) для мониторинга времени выполнения, использования ресурсов, пропускной способности каждого приложения до уровня метода.

 

Ответ 4

Я хотел бы поделиться с вами самодельной функцией, которую я использую для измерения скорости любой существующей функции до 10 аргументов:

function fdump($f_name='', $f_args=array()){

    $f_dump=array();

    $f_result='';

    $f_success=false;

    $f_start=microtime();

    $f_start=explode(' ', $f_start);

    $f_start=$f_start[1] + $f_start[0];

    if(function_exists($f_name)){

        if(isset($f_args[0])&&is_array($f_args[0])){

            if($f_result=$f_name($f_args)){

                $f_success=true;

            }

        } elseif(!isset($f_args[1])){

            if($f_result=$f_name($f_args[0])){

                $f_success=true;

            }

        } elseif(!isset($f_args[2])){

            if($f_result=$f_name($f_args[0],$f_args[1])){

                $f_success=true;

            }

        } elseif(!isset($f_args[3])){

            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2])){

                $f_success=true;

            }

        } elseif(!isset($f_args[4])){

            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3])){

                $f_success=true;

            }

        } elseif(!isset($f_args[5])){

            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4])){

                $f_success=true;

            }

        } elseif(!isset($f_args[6])){

            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5])){

                $f_success=true;

            }

        } elseif(!isset($f_args[7])){

            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6])){

                $f_success=true;

            }

        } elseif(!isset($f_args[8])){

if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7])){

                $f_success=true;

            }

        } elseif(!isset($f_args[9])){

if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8])){

                $f_success=true;

            }

        } elseif(!isset($f_args[10])){

if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8],$f_args[9])){

                $f_success=true;

            }

        }

    }

    $f_end=microtime();

    $f_end=explode(' ', $f_end);

    $f_end=$f_end[1] + $f_end[0];

    $f_time=round(($f_end - $f_start), 4);

    $f_dump['f_success']=$f_success;

    $f_dump['f_time']=$f_time;

    $f_dump['f_result']=$f_result;

    var_dump($f_dump);exit;

    //return $f_result;

}

 Пример:

function do_stuff($arg1='', $arg2=''){

    return $arg1.' '.$arg2;

}

fdump('do_stuff',array('hello', 'world'));

Результат:

array(3) {

    ["f_success"] => bool(true)

    ["f_time"]     => float(0)            //слишком быстро...

    ["f_result"]    > string(11) "hello world"

  }

 

Ответ 5

Для расчета необходимого времени можно использовать такие базовые вещи, как хранение временных меток или microtime() до и после операции. Это легко сделать, но не очень точно. Возможно, лучшим решением будет Xdebug. Я никогда не работал с ним, но, похоже, это самый известный отладчик/профайлер PHP, который я смог найти.

 

Ответ 6

Если вы хотите быстро протестировать производительность фреймворка, вы можете поместить в файл index.php:

//в начале

$milliseconds = round(microtime(true) * 1000);

//и в конце

echo round(microtime(true) * 1000) - $milliseconds;

 Каждый раз вы будете получать время выполнения в миллисекундах. Потому что микросекунды не слишком полезны при тестировании фреймворка.

 

Схожие статьи

Web

Как проверить, является ли массив PHP ассоциативным или последовательным

Web

Как узнать, установлен ли флажок в PHP

Поиск по GitHub: как найти репозитории, нужный код или разработчика?
Web

Поиск по GitHub: как найти репозитории, нужный код или разработчика?

Web

Как удалить куки