#php #performance #profiler #xdebug
#php #Производительность #профилировщик #xdebug
Вопрос:
Я использую XDebug в качестве профилировщика для PHP-приложения. Я столкнулся с ситуацией, когда XDebug сильно изменяет результаты в такой степени, что они бесполезны.
Вот упрощенный пример, демонстрирующий проблему:
function foo(){ $x = 1; }
function bar(){ foo(); }
Протестируйте:
$t0 = microtime(true);
for ($i = 0; $i < 1000000; $i ) foo();
echo microtime(true) - $t0;
Тест B:
$t0 = microtime(true);
for ($i = 0; $i < 1000000; $i ) bar();
echo microtime(true) - $t0;
Итак, вот результаты, которые я получаю (в секундах):
profiler | profiler > profiler
disabled | enabled > results
--------------------------------------------------------------------
output | output > total time time in foo() time in bar()
Test A 0.159 | 12.199 > 12.245 0.110 - (not called)
Test B 0.233 | 25.399 > 25.578 0.104 11.068
Ожидается увеличение времени выполнения из-за дополнительных вызовов профилировщика. Также ожидается небольшое различие между выводом на основе микротайма и результатами профилировщика. Я несколько раз повторял тесты, и результаты всегда были одинаковыми.
Из результатов, взятых из теста B с отключенным профилировщиком, мы можем сказать, что скрипт тратит около 0,159 секунды на foo() и 0,074 секунды на bar() . Очевидно, что время, затраченное на bar(), меньше времени, затраченного на foo() .
Однако, когда я анализирую результаты профилировщика (с помощью qcachegrind), время, показанное как затраченное в bar() (= 11,068 секунды), смехотворно выше, чем время в foo() (= 0,104 секунды).). Этому есть возможное объяснение: каждый раз, когда выполняется вызов функции, профилировщик запускает дополнительный код, чтобы отслеживать время, затраченное на вызов. Я полагал, что это исключило это дополнительное время из результатов, но, видимо, это не так.
[РЕДАКТИРОВАТЬ] В результате профилировщик сообщает, что bar() в этой программе занимает больше времени, чем foo(), что не так, поскольку мы измерили с отключенным профилировщиком. Это даже близко не так! Относительные результаты (процент времени, затраченного каждой функцией) совершенно неверны. Этого не следует ожидать, потому что, если это так, профилировщик не может указать, какая функция занимает большую часть времени. Хотя ожидается, что абсолютное время будет иметь (большие) различия, относительное время не должно иметь. [/ ПРАВИТЬ]
Это делает результаты непригодными для использования. Любой более модульный код (с большим количеством вызовов функций, оболочек, объектов и т.д.) строго наказывается, хотя он не настолько медленный!
Итак, вопрос: есть ли какой-либо способ сообщить XDebug игнорировать или отдельно отслеживать дополнительное время, затраченное на вызовы профилировщика?
Комментарии:
1. Не по теме, но я слышал о XHProf , который можно использовать в производстве, потому что, как говорят, он не влияет на производительность.
2. @greg0ire, я протестировал XHProf. Он работает лучше, чем XDebug, и у него нет проблемы, которую я описал. Тем не менее, странно, что у XDebug, самого распространенного профилировщика для PHP, такая серьезная проблема, и никто не жаловался.
3. Я думаю, это все еще позволяет увидеть, где проблемы в большинстве случаев. Или, возможно, есть способ игнорировать дополнительное время, затраченное на вызовы профилировщика…
4. Не могли бы вы опубликовать файл профиля? Я ‘
Ответ №1:
Известно, что xdebug ведет себя подобным образом, и на самом деле никаких новостей. Извините, очевидно, это новость для вас, и я не хочу сказать, что все должны это знать.
В качестве пояснения: xdebug выполняет всю работу, от начала до конца, сбрасывая / метрифицируя все, как было объявлено. За это приходится платить (как это не могло быть?).
Если вам нужно выбрать показатели в изолированном контексте в вашем скрипте, вы не должны запускать xdebug. Или, как показывает ваш вопрос: вы пытаетесь профилировать xdebug с включенным xdebug (с кодом PHP!). На самом деле это не сработает, вы не можете профилировать скомпилированное PHP расширение C с помощью пользовательского кода PHP, или, по крайней мере, я не буду этому доверять. Представьте, что библиотека изменяет поведение интерпретатора, того же интерпретатора, на котором выполняется ваш код профилирования.
Если вам действительно нужно изолировать определенную часть вашего изолированного кода, xdebug просто не является подходящим инструментом. Ищите xhprof или, может быть, в реальной среде Pinba.
Комментарии:
1. Извините, но я не собираюсь профилировать сам XDebug. Я хочу профилировать две версии моего кода в целом. В первой версии много вызовов функций, а в другой — нет. XDebug серьезно наказывает первую версию, и поэтому она бесполезна. Да, это новость для меня, и я не согласен с тем, что я должен был ожидать от профилировщика такого поведения. — Однако я согласен использовать xhprof, я играл с ним последние дни, и результаты очень хорошие.
2. @linepogl: Я хотел сказать, что вы намерены профилировать XDebug. Я просто хотел сказать, что вы это сделали, и что это, скорее всего, не работает с кодом пользователя PHP. Это небольшая разница, которую я хотел прояснить, в каких задачах вы можете выполнить с помощью такого способа «проверки». Только то, что 🙂 Это не бесполезно, просто xdebug, скорее всего, не подходит для этой работы (профилирование изолированных частей).
3. @hakre: пожалуйста, используйте прямую ссылку на pinba.org вместо того, чтобы использовать свой собственный блог
Ответ №2:
вы не должны ожидать, что результаты профилировщиков будут такими же, как при обычной работе, это невозможно (или вам нужно замедлить работу, которая нежелательна)
но все же время в de profiler очень полезно, например, вы можете видеть, что если выполнение сценария занимает больше времени, результаты (некоторые wat) совпадают со scale
использование профилировщиков полезно для выявления проблемных мест, но результаты не могут быть такими же, как в реальной жизни, чтобы оптимизировать оптимизацию (по крайней мере, с помощью xdbug)
Комментарии:
1. Как я уже сказал в вопросе, у меня нет проблем с дополнительным временем. И, как вы говорите, роль профилировщиков заключается в определении точек, где программа проводит большую часть времени. Следует ожидать, что относительное время, проведенное в функции, не сильно зависит от профилировщика. Однако в этом случае профилировщик сообщает, что программа проводит большую часть своего времени в пустой функции…
2. да, и для вашего кода это 0,233 — 0,159 = 0,074 секунды,
bar()
что составляет 31% от затраченного времени,3. Конечно, время профилирования не может быть таким же, как время выполнения кода в рабочей среде, но, по крайней мере, должно быть пропорциональным, чего нет, что делает xdebug довольно бесполезным для профилирования, по крайней мере, в моем случае.
Ответ №3:
Обязательно попробуйте xhprof
. Кажется менее подверженным ошибкам. Не стучать Xdebug
.
Ответ №4:
К сожалению, это невозможно. Я больше не использую XDebug в качестве профилировщика, и я предлагаю, чтобы никто не использовал его.