Путаница интерпретации KCachegrind

Я пытаюсь понять значения, показанные в Kcachegrind на левой панели

У меня есть Incl. (который я прочитал в руководстве, включительно), Self, Called a Function

Теперь я анализирую этот файл cachegrind, и у меня есть

Incl. ---- Self ---- Called ---- Function

100.05 ---- 0.04 ---- (0) ---- {main}

83.38 ---- 0.07 ---- 250 --- item->close

78.85 ---- 78.85 ---- 10 067 ---- php::mysql_query

и список продолжается.

Но вот моя проблема.

Я думаю, что item- > close - это мое узкое место, но я не понимаю, как он имеет 83.38 из Inclusive, а затем 0.07 of Self, а команда mysql_query имеет то же самое в обоих.

Что означает "я" здесь?

Также как эти проценты соотносятся друг с другом? Я не понимаю, как item- > close занимает 83%, а mysql_query занимает 78%

Спасибо

Ответ 1

"self" означает время, занимаемое этой функцией, но не от любых функций, которые она вызывает. Если "Я" низкий и "вкл." является высоким, то лучшим местом для оптимизации является, вероятно, один из детей (например, называемые функции). В этом случае, похоже, что mysql-запрос занимает большую часть времени, поэтому вы, вероятно, захотите оптимизировать запрос (если это возможно). Причина, по которой mysql_qeury имеет "self" == "incl." заключается в том, что профилировщик не может видеть в функции, поскольку он выполняет свою работу за пределами php-runtime (например, в клиентской библиотеке mysql).

Я могу добавить, что 10067 звонков в mysql_query выглядит очень подозрительно. Запрос базы данных - очень дорогостоящая операция. Вы уверены, что каким-то образом вы не можете уменьшить количество запросов?

Edit:

Я могу попробовать. Но как насчет Incl. Как это 80 в конце, а затем 70 в запросе mysql, как это связано с общим процентом, который должен быть 100%

Номера не должны складываться. То, что вы смотрите, - это отсортированный список времени целого, который выполняет эти функции. Это не граф вызовов (хотя это часто случается так или иначе имитировать).

Предположим, что следующий код:

function fn1() {
  sleep(1);
  fn2();
}
function fn2() {
  sleep(98);
}
function fn3() {
  sleep(1);
}
fn1();
fn3();

Что может генерировать следующий вывод:

name | incl. | self
main | 100%  | 0%
fn1  | 99%   | 1%
fn2  | 98%   | 98%
fn3  | 1%    | 1%

Когда вы сортируете список по "вкл." , вы смотрите на функции, которые медленны в совокупности. Другими словами, те, кто высоко оценивают здесь, не обязательно медленны, но они называют другие функции. Если функция высоко оценивает значение "вкл." и у вас много вызовов, вы должны попытаться уменьшить количество вызовов этой функции или позволить кеше кеша его результата (работает только если это запрос, а не действие).

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

Ответ 2

Self означает время, затраченное на выполнение функции, исключая любые функции, которые он вызывает.

Например:

function foo()
{
    bar();
}

function bar
{
    sleep(1);
}

foo();

Это даст вам:

Incl    Self   Func
1       0      foo
1       0      bar
1       1      sleep <- Here the bottleneck!