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

131

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

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

Я хочу протестировать и протестировать различные функции PHP, которые делают то же самое. Например, preg_matchvs strposили domdocumentvs 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.

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

Эрик
источник
Прочтите эту статью: rakesh.sankar-b.com/2011/01/12/echo-print-which-is-fast-php - надеюсь, это поможет.
Ракеш Санкар
4
0,015 секунды. Средняя скорость моргания глаза - 0,3 секунды. Вам действительно, действительно, действительно нужно улучшить эту скорость, могу я спросить, почему?
Бен
4
@ben, это пример, у меня есть страницы, которые загружаются за 0,8 секунды с более чем 50 000 посетителей в час, мне нужно убедиться, что страница загружается быстро,
Эрик
8
@MarcB Amazon, по-видимому, проверил и обнаружил, что задержка в 100 мс вызвала снижение продаж на 1%. Для такого большого сайта, как Amazon, это могут быть миллиарды. highscalability.com/…
ceejayoz 04
1
@ceejayoz Да, если вы amazon, это большая проблема, но если нет, то остерегайтесь погони за безумным временем загрузки страницы ради этого. Amazon выполнила свою домашнюю работу и поэтому может легко оправдать потраченное X человеко-часов на восстановление Y падения продаж. Урок здесь - делайте домашнее задание!
Джеймс Батлер

Ответы:

123

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

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

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

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

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

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

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

Джеймс Батлер
источник
6
Если это действительно ответ на ваш вопрос, Эрик, я считаю, что ваши вопросы сформулированы неправильно (или, может быть, я просто неправильно его прочитал) Исходя из вашего вопроса, похоже, что вы хотели изолировать разные методы выполнения одного и того же действия в PHP и определить, какой из них является самым быстрым. Однако, судя по ответам, которые вы приняли и назначили награду, похоже, что вас больше интересовало нагрузочное тестирование всего веб-стека, а это совсем другое дело.
Alec Gorge
Xdebug не поддерживает скрипты в кодировке Ioncube. Как вы выполняете эти сценарии?
BigSack
@BigSack Здесь ты вроде как сам по себе, я никогда не пробовал профилировать что-либо, что так запутано. Сначала я бы попробовал XHProf, так как его относительно легко запустить. Вы можете обнаружить, что IonCube полностью мешает работе любого профилировщика, не являющегося пользователем.
Джеймс Батлер
1
Заявление Nginx vs Apache немного предвзято. Большинство игнорируют, AllowOverideзаставляя Apache просматривать целые каталоги для файлов .htaccess при каждом запросе. Уже одно это уводит Apache с его собственного пути.
B00MER
74

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

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

Книга Зевса
источник
30

Вы захотите взглянуть на 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, которую я написал для себя.

Алек Гордж
источник
8
кажется очень сложным, я ничего не понимаю
Эрик
Какую часть вы не понимаете? Настройка или анализ данных?
Alec Gorge
1
ну установки нет, это никогда не будет работать на моем сервере, но данные, все это маленькие коробки, которые я не могу прочитать
Эрик
13
потому что я не использую окна
Эрик
2
+1 для XDebug + KCacheGrind. Это действительно полезно и на удивление легко установить и использовать. Я использую его в течение довольно долгого времени, вы получаете дополнительный бонус - когда вы знакомы с ним, вы можете использовать KCacheGrind с Valgrind (+ memgrind / callgrind) для профилирования гораздо большего количества других языков (и не только времени процессора).
XzKto 05
16

Попробуйте 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
)
fotuzlab
источник
2
Прекрасный дизайн интерфейса (как я вижу, вы являетесь автором), рада! (И спасибо за использование "ProperCase";) имен методов (вроде SetMemory()) вместо уродливой, но все же вездесущей mixedCase()чуши, которая в любом случае практически бессмысленна в PHP. Вы, наверное, слишком стары. ;))
Sz.
1
Полностью устарел, но за пару минут я превратил его во что-то приятное и полезное (даже в windows). Я попробую посмотреть, смогу ли я сделать запрос на перенос.
Tomas Gonzalez
7

Я бы посмотрел на xhprof . Не имеет значения, запущен ли он на cli или через другой сапи (например, 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 папки, вы сваливать на сервере и с минимальной конфигурацией, вы можете визуализировать данные , собранные и начать бурение вниз.

НТН!

Пока
источник
3

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

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

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

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

Алэсдэйр
источник
1

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

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

козел
источник
0

Эрик,

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

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

TerryE
источник
0

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

Ритеш Ариал
источник