Что я делаю, так это добавляю отладочные вызовы из каждой функции. В функции отладки я бы затем измерил время с момента последнего вызова отладки, добавив это время в виде строки к началу строки для трассировки следующим образом:
[-] ввод для цикла
[4ms] выход из цикла
Затем вы распыляете и молитесь со следами, находя куски кода, которые работают медленно, что может быть больше 1 мс / вызов.
Объедините это с группировкой / анализом трасс по кадрам, и у вас неожиданно появится очень мощный инструмент.