Я хочу рассказать Вам о моем маленьком open-source проекте, который может показаться интересным людям, профилирующим PHP-приложения с помощью Xdebug. Как многим из Вас известно, в результате работы Xdebug'а получаются логи в формате cachegrind. Их, в свою очередь, можно анализировать с помощью старого доброго KCachegrind, можно разбирать посредством Webgrind, CachegrindVisualizer, и т.д. Но я решил пойти другим путем, и вот что у меня получилось...
Итак, встречаем xdebugtoolkit! Это набор простых утилиток, основная из которых - cg2dot - умеет преобразовывать файлы Xdebug'а в вид понятных раскрашенных деревьев вызовов в формате dot, для просмотра которых рекомендую другую утилитку - xdot.
Одной из своих находок, еще со времен работы над cachegrindvisualizer, я считаю то, что мне удалось сделать максимально компактные графы вызовов, не выходя за рамки древовидности. Это проще всего показать сразу на примере. Такой код, несмотря на множественные переиспользования функций, после агрегации выглядит таким образом:
Как видно, агрегируются только вызовы с одинаковыми путями. Например, вызовы функции d с путями
root -> {main} -> a -> c -> dагрегируются между собой, но не с вызовами по путям
root -> {main} -> b -> c -> dДля сравнения, вот что бывает, когда граф перестает быть деревом.
Цвет каждой ноды состоит из двух компонент:
Желтый цвет - кол-во вызовов. Чисто жёлтым вызовом будет тот, который вызывали максимальное кол-во раз, но который при этом очень быстро отработал.
Сиреневый - собственное (без подвызовов) затраченное время. Чисто сиреневым будет единичный вызов с максмальным собственным временем.
Складывая желтый и сиреневый, получаем красный - такое бывает в случае большого кол-ва вызовов одной и той же функции, которые в сумме имеют очень большой self time.
Планы по дальнейшей разработке можно посмотреть в issues на google code.
PS: тому, что xdebugtoolkit написан на питоне, есть одно простое объяснение: проект начинался как реальная задача, на которой я хотел узнать питон получше. Производительность меня интересовала всегда, поэтому я решил совместить приятное с полезным.