Я использую XDebug как профилировщик для PHP-приложения. Я столкнулся с ситуацией, когда XDebug сильно меняет результаты в такой степени, что они бесполезны.
Здесь приведен упрощенный пример для демонстрации проблемы:
function foo(){ $x = 1; }
function bar(){ foo(); }
Тест A:
$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 с отключенным профилировщиком можно сказать, что script тратит около 0,159 секунды в foo() и 0,074 секунды в bar(). Очевидно, что время, проведенное в bar(), меньше времени, проведенного в foo().
Однако, когда я анализирую результаты профилировщика (с qcachegrind), время, показанное как потраченное в bar() (= 11.068 секунд), смехотворно выше, чем время в foo() (= 0,104 секунды). Для этого есть возможное объяснение: каждый раз при вызове функции профайлер запускает дополнительный код для отслеживания времени, затраченного на вызов. Я полагал, что он исключил это дополнительное время из результатов, но, по-видимому, этого не делает.
[EDIT] В результате профайлер говорит, что bar() занимает больше времени, чем foo() в этой программе, что не так, как мы измеряли с отключенным профилировщиком. Это даже не близко! Относительные результаты (процент времени, затрачиваемого каждой функцией) полностью ошибочны. Этого нельзя ожидать, потому что, если это так, профилировщик не может указать, какая функция занимает большую часть времени. Хотя ожидается, что абсолютные времена будут иметь (большие) различия, относительных времен не должно быть. [/EDIT]
Это делает результаты непригодными. Любой код, который является более модульным (с большим количеством вызовов функций, оберток, объектов и т.д.), Строго наказывается, хотя это не так медленнее!
Итак, вопрос: есть ли способ сказать XDebug игнорировать или отслеживать отдельно дополнительное время, потраченное на вызовы профайлера?