Как оценить эффективность PHP-скрипта

Я хочу знать, как лучше всего сравнить мои PHP-скрипты. Не имеет значения, является ли работа cron или веб-страницей или веб-службой.

Я знаю, что могу использовать microtime, но действительно ли он дает мне реальное время PHP-скрипта?

Я хочу протестировать и сравнить различные функции в PHP, которые делают то же самое. Например, preg_match против strpos или же domdocument против preg_match или preg_replace vs str_replace`

Пример веб-страницы:

<?php
// login.php

$start_time = microtime(TRUE);

session_start(); 
// do all my logic etc...

$end_time = microtime(TRUE);

echo $end_time - $start_time;

Это выдаст: 0.0146126717 (меняется все время - но это последнее, что я получил). Это означает, что для выполнения скрипта PHP потребовалось около 0,015.

Есть ли способ лучше?

9 ответов

Решение

Если вы действительно хотите тестировать реальный код, используйте такие инструменты, как Xdebug и XHProf.

Xdebug отлично подходит для тех случаев, когда вы работаете в dev/staging, а XHProf - отличный инструмент для производства, и его можно безопасно запускать там (пока вы читаете инструкции). Результаты любой загрузки одной страницы не будут столь же значимыми, как наблюдение за тем, как работает ваш код, в то время как сервер заставляет выполнять еще миллион задач, а ресурсы становятся недостаточными. Это поднимает другой вопрос: вы узкое место на процессоре? БАРАН? I/O?

Вы также должны смотреть не только на код, который вы запускаете в своих скриптах, на то, как обслуживаются ваши скрипты / страницы. Какой веб-сервер вы используете? В качестве примера я могу сделать так, чтобы nginx + PHP-FPM серьезно выполнял mod_php + Apache, который, в свою очередь, сталкивается с проблемами при обслуживании статического контента с использованием хорошего CDN.

Следующее, что нужно рассмотреть, это то, что вы пытаетесь оптимизировать?

  • Является ли скорость, с которой страница отображается в браузере пользователя, приоритетом номер один?
  • Является ли целью получение каждого запроса к серверу как можно быстрее при минимальном потреблении ресурсов процессора?

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

Надеемся, что все вышеперечисленное может помочь показать, что тщательно изолированное "лабораторное" тестирование не будет отражать переменные и проблемы, с которыми вы столкнетесь при производстве, и что вы должны определить, какова ваша цель высокого уровня, а затем то, что вы можете сделать, чтобы туда попасть, перед тем, как отправиться в путь микро / преждевременной оптимизации в ад.

Чтобы оценить, насколько быстро ваш полный скрипт выполняется на сервере, есть множество инструментов, которые вы можете использовать. Сначала убедитесь, что ваш скрипт (например, preg_match vs strpos) должен вывести те же результаты, чтобы квалифицировать ваш тест.

Ты можешь использовать:

Вы захотите взглянуть на Xdebug и, более конкретно, на возможности профилирования Xdebug.

По сути, вы включаете профилировщик и каждый раз, когда загружаете веб-страницу, он создает файл cachegrind, который может быть прочитан с помощью WinCacheGrind или KCacheGrind.

Xdebug может быть немного сложно настроить, так что вот соответствующий раздел моего php.ini для справки:

[XDebug]
zend_extension = h:\xampp\php\ext\php_xdebug-2.1.1-5.3-vc6.dll
xdebug.remote_enable=true
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_dir=h:\xampp\cachegrind
xdebug.profiler_output_name=callgrind.%t_%R.out

И вот скриншот .out файл в WinCacheGrind:

введите описание изображения здесь

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

Если вам интересно, это всего лишь старая версия CMS, которую я написал для собственного использования.

Попробуйте https://github.com/fotuzlab/appgati

Это позволяет определять шаги в коде и сообщает время, использование памяти, нагрузку на сервер и т.д. между двумя шагами.

Что-то вроде:

    $appgati->Step('1');

    // Do some code ...

    $appgati->Step('2');

    $report = $appgati->Report('1', '2');
    print_r($report);

Пример выходного массива:

Array
(
    [Clock time in seconds] => 1.9502429962158
    [Time taken in User Mode in seconds] => 0.632039
    [Time taken in System Mode in seconds] => 0.024001
    [Total time taken in Kernel in seconds] => 0.65604
    [Memory limit in MB] => 128
    [Memory usage in MB] => 18.237907409668
    [Peak memory usage in MB] => 19.579357147217
    [Average server load in last minute] => 0.47
    [Maximum resident shared size in KB] => 44900
    [Integral shared memory size] => 0
    [Integral unshared data size] => 0
    [Integral unshared stack size] => 
    [Number of page reclaims] => 12102
    [Number of page faults] => 6
    [Number of block input operations] => 192
    [Number of block output operations] => 
    [Number of messages sent] => 0
    [Number of messages received] => 0
    [Number of signals received] => 0
    [Number of voluntary context switches] => 606
    [Number of involuntary context switches] => 99
)

Я бы посмотрел в xhprof. Не имеет значения, запускается ли он на cli или через другой sapi (например, fpm или fcgi или даже модуль Apache).

Самое приятное в xhprof - это то, что он достаточно пригоден для запуска в производство. Что-то, что не работает так же хорошо с xdebug (в прошлый раз, когда я проверял). xdebug влияет на производительность, а xhprof (я бы не сказал, что его нет) справляется намного лучше.

Мы часто используем xhprof для сбора образцов с реальным трафиком, а затем анализируем оттуда код.

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

Как только расширение скомпилировано и загружено, вы начинаете профилирование в коде с помощью:

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

Прекратить:

$xhprof_data = xhprof_disable();

Затем сохраните данные в файл или базу данных - что угодно, что плавает на вашей лодке и не прерывает обычную среду выполнения. Мы асинхронно передаем это на S3, чтобы централизовать данные (чтобы можно было увидеть все запуски со всех наших серверов).

Код на github содержит папку xhprof_html, которую вы выгружаете на сервер, и с минимальной конфигурацией вы можете визуализировать собранные данные и начать детализацию.

НТН!

Поместите это в for цикл, чтобы сделать каждую вещь 1 000 000 раз, чтобы получить более реалистичное число. И запускайте таймер только перед тем, как код, который вы действительно хотите сравнить, затем записывайте время окончания сразу после (т.е. не запускайте таймер до session_start(),

Также убедитесь, что код идентичен для каждой функции, которую вы хотите сравнить, за исключением функции, которую вы синхронизируете.

То, как выполняется скрипт (cronjob, php из командной строки, Apache и т. Д.), Не должно иметь значения, поскольку вы только синхронизируете относительную разницу между скоростью различных функций. Так что это соотношение должно остаться прежним.

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

Хорошее начало - использовать xdebugs profiler http://xdebug.org/docs/profiler

Возможно, это не самая простая установка и использование, но как только вы ее запустите, огромные объемы данных и удобство просмотра незаменимы.

Мой ответ получен от: /questions/1059820/kak-zapustit-funktsiyu-1000-raz-i-vernut-microtime-togo-skolko-vremeni-eto-zanyalo/1059821#1059821

<?php
function yourFunction(){
  echo 'Code Im benchmarking';
}

$time_start = microtime(true);

$times=0;               // This couldn't be tough
while($times<1000)
{
   yourFunction();
   $times++;
}


$time_end = microtime(true);
$time = $time_end - $time_start;

echo "Did yourFunction in $time seconds\n";
?>

Просто измените код в вашей функции для тестирования.

Эрик,

Вы задаете себе неправильный вопрос. Если ваш скрипт выполняется в ~15 мсек, то его время в значительной степени не имеет значения. Если вы используете общую службу, активация образа PHP займет ~100 мсек, чтение в файлах сценариев ~30-50 мсек, если полностью кэшировано на сервере, возможно, 1 или более секунд при загрузке из внутренней фермы NAS. Сетевые задержки при загрузке страницы мебели могут добавить много секунд.

Основной проблемой здесь является восприятие пользователем времени загрузки: сколько времени ему или ей приходится ждать между нажатием на ссылку и получением полностью отображаемой страницы. Взгляните на Google Page Speed, которую вы можете использовать как расширение Ff или Chrome, и документацию по Pagespeed, в которой подробно обсуждается, как добиться хорошей производительности страницы. Следуйте этим рекомендациям и постарайтесь, чтобы ваши оценки страниц были лучше, чем 90/100. (Главная страница Google оценивает 99/100, как и мой блог). Это лучший способ получить хорошую воспринимаемую пользователем производительность.

Также полезно следить за своим PHP-кодом и перепроверить эту ссылку, чтобы убедиться, что само ваше кодирование потенциально не влияет на производительность приложения.

Другие вопросы по тегам