Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Профайлер

Ви запускаєте свою гру від Godot і граєте. Це весело, він стає повним, і ви відчуваєте, що він наближається до випуску.

Але потім ви відкриваєте дерево навичок, і воно зупиняється, оскільки щось зачіпає ваш код. Спостерігати, як дерево навичок прокручується, ніби це слайд-шоу, неприйнятно. Що пішло не так? Це позиціонування елементів дерева навичок, інтерфейсу користувача чи візуалізації?

Ви можете спробувати все оптимізувати та запускати гру неодноразово, але ви можете бути розумнішими щодо цього та звузити можливості. Введіть профайлер Godot.

Огляд профайлера

Ви можете відкрити профайлер, відкривши панель Debugger і натиснувши вкладку Profiler.

../../../_images/profiler.png

Профайлер Godot не запускається автоматично, оскільки профілювання потребує продуктивності. Він повинен постійно вимірювати все, що відбувається в грі, і повідомляти про це налагоджувачу, тому його вимкнено за замовчуванням.

Щоб розпочати профілювання, запустіть гру, а потім поверніться до редактора. Натисніть кнопку Пуск у верхньому лівому куті вкладки Профайлер. Ви також можете позначити Автозапуск, який змусить профайлер автоматично запуститися під час наступного запуску проекту. Зауважте, що стан прапорця Автозапуск не зберігається в сеансах редактора.

Примітка

Профайлер наразі не підтримує сценарії C#. Сценарії C# можна профілювати за допомогою JetBrains Rider і JetBrains dotTrace із плагіном підтримки Godot.

Ви можете будь-коли очистити дані, натиснувши кнопку Очистити. Використовуйте спадне меню Виміряти, щоб змінити тип вимірюваних даних. Панель вимірювань і графік оновляться відповідно.

Виміряні дані

Інтерфейс профайлера розділений на два. Ліворуч є список функцій, а праворуч – графік продуктивності.

Основними вимірюваннями є час кадру, фізичний кадр, час простою та час фізики.

  • Час кадру — це час, який потрібен Godot, щоб виконати всю логіку всього зображення, від фізики до візуалізації.

  • Фізичний кадр — це час, виділений Godot між оновленнями фізики. В ідеальному сценарії час кадру — це те, що ви вибрали: 16,66 мілісекунди за замовчуванням, що відповідає 60 кадрам/с. Це система відліку, яку можна використовувати для всього іншого навколо.

  • Час простою – це час, який Godot знадобився для оновлення логіки, окрім фізики, наприклад коду, який живе в _process, або таймерів і камер, налаштованих на оновлення в Idle.

  • Час фізики – це час, який Godot витратив на оновлення фізичних завдань, таких як _physics_process та вбудованих вузлів, для яких встановлено режим оновлення Фізики.

Примітка

Час кадру включає час візуалізації. Скажімо, ви виявили таємничий сплеск затримки у своїй грі, але ваша фізика та скрипти працюють швидко. Затримка може бути через появу частинок або візуальних ефектів!

За замовчуванням Godot відзначає час кадру та час фізики. Це дає вам загальне уявлення про те, скільки часу займає кожен кадр відносно виділеної бажаної фізики FPS. Ви можете вмикати та вимикати функції, натискаючи прапорці ліворуч. Інші об’єкти з’являються, коли ви спускаєтесь у списку, як-от Physics 2D, Physics і Audio, перш ніж досягти функцій сценарію, де з’являється ваш код.

Якщо ви клацнете на графіку, ви зміните інформацію про кадр, який з’явиться ліворуч. У верхньому правому куті також є лічильник кадрів, де ви можете вручну налаштувати рамку, на яку ви дивитеся, більш детально.

Область вимірювання та вимірювальні вікна

Ви можете змінити вимірювання, яке ви дивитесь, за допомогою спадного меню Виміряти. За замовчуванням він починається з Frame Time і вказує час, необхідний для проходження кадру в мілісекундах. Середній час – це середній час, який знадобилася будь-якій даній функції під час виклику більше одного разу. Наприклад, функція, для виконання якої знадобилося 0,05 мілісекунди п’ять разів, повинна дати вам у середньому 0,01 мілісекунди.

Якщо точний підрахунок мілісекунд не важливий, і ви хочете побачити пропорції часу відносно решти кадру, використовуйте вимірювання у відсотках. % кадру — це відносно часу кадру, а % фізики — відносно часу фізики.

Останній варіант - розмах часу. Включно вимірює час, який знадобилася функції з будь-якими викликами вкладених функцій. Наприклад:

../../../_images/split_curve.png

get_neighbors, find_nearest_neighbor і move_subject зайняли багато часу. Вас можуть обдурити, подумавши, що це тому, що всі вони повільні.

Але коли змінено на Self, Godot вимірює час, проведений у тілі функції, без урахування викликів функцій, які він зробив сам.

../../../_images/self_curve.png

Ви бачите, що get_neighbors і move_subject значно втратили свою важливість. По суті, це означає, що get_neighbors і move_subject витратили більше часу на очікування завершення виклику іншої функції, а find_nearest_neighbor насправді повільно.

Налагодження повільного коду за допомогою профайлера

Пошук повільного коду за допомогою профайлера зводиться до запуску вашої гри та спостереження за графіком продуктивності, коли він малює. Якщо під час кадру виникає неприйнятний сплеск, ви можете натиснути на графік, щоб призупинити гру та звузити _Кадр #_ до початку сплеску. Щоб знайти першопричину, вам може знадобитися переходити між кадрами та функціями.

У розділі «Функції сценарію» встановіть прапорці для деяких функцій, щоб визначити, які потребують часу. Це функції, які вам потрібно переглянути та оптимізувати.

Вимірювання вручну за мікросекунди

Якщо ваша функція складна, може бути важко визначити, яка частина потребує оптимізації. Це ваша математика чи спосіб доступу до інших фрагментів даних для виконання математики? Це цикл "for"? Твердження «якщо»?

Ви можете звузити вимірювання, вручну підраховуючи тики під час виконання коду з деякими тимчасовими функціями. Ці дві функції є частиною об’єкта класу Time. Це get_ticks_msec і get_ticks_usec. Перший вимірюється в мілісекундах (1 001 за секунду), а другий вимір. в мікросекундах (1 000 001 за секунду).

Будь-який з них повертає кількість часу з моменту запуску ігрового механізму за відповідний проміжок часу.

Якщо ви обернете фрагмент коду з початковим і кінцевим відліком мікросекунд, різниця між ними полягає в кількості часу, який знадобився для виконання цього фрагмента коду.

# Measuring the time it takes for worker_function() to run
var start = Time.get_ticks_usec()
worker_function()
var end = Time.get_ticks_usec()
var worker_time = (end-start)/1000000.0

# Measuring the time spent running a calculation over each element of an array
start = Time.get_ticks_usec()
for calc in calculations:
    result = pow(2, calc.power) * calc.product
end = Time.get_ticks_usec()
var loop_time = (end-start)/1000000.0

print("Worker time: %s\nLoop time: %s" % [worker_time, loop_time])

Коли ви стаєте більш досвідченим програмістом, ця техніка стає менш необхідною. Ви починаєте дізнаватися, які частини запущеної програми є повільними. Знання про те, що петлі та розгалуження можуть бути повільними, випливає з досвіду, і ви отримуєте досвід, вимірюваючи та проводячи дослідження.

Але між профайлером і функціями тиків у вас має бути достатньо, щоб почати знаходити, які частини вашого коду потребують оптимізації.