С помощью выражения profile можно измерять производительность некоторого фрагмента кода в программе. Ниже приведён синтаксис использования выражения profile в блоке кода.
code-before
profile:
code-to-measure
code-afterВ этом примере медленный код представляет собой блок кода, время выполнения которого нужно измерить. При выполнении кода время в миллисекундах между входом и выходом из блока кода profile сохраняется в Журнале выходных данных в UEFN.
Результаты измерения времени выполнения кода сохраняются в форме LogVerse: VerseProfile: 0.023900 ms. Если в коде есть несколько выражений profile и нужно идентифицировать выводимые данные, можно добавить к выражению profile строку пользовательских тегов:
profile(“User String to Categorize Output”):
code-to-measureПри выполнении кода из этого примера в журнале сохранится строка LogVerse: VerseProfile: Пользовательская строка для описания выводимых данных 0.023900 ms.
Если вы используете выражение profile в контексте, допускающем неоднозначность, в котором также есть сохранение данных в журнале, то все выводимые данные profile сохранятся в журнале выходных данных первыми, независимо от порядка следования выражений profile и вызовов print в коде.
Если в блоке кода profile есть выражение defer, то выражение defer также будет учитываться при подсчёте времени, но будет выполняться последним при выходе из блока кода profile.
MyFunction1():void=
defer:
MyFunction2() # code is not profiled
profile:
defer:
MyFunction3() # code is profiled and run last
MyFunction4() # code is profiled and run firstРезультат
В Verse всё, включая profile, является выражением, то есть имеет результат. Выражение profile передаёт значения результата таким же образом, как выражения if.
В этом примере MyFunction возвращает некоторое значение, которое передаётся через выражение profile и сохраняется в переменной ResultOfFunction. Это означает, что вы можете упросить контрольно-проверочный код вокруг вызовов функций и использовать результаты вызовов функций за пределами области видимости блока кода profile.
ResultOfFunction := profile(“MyFunction”):
MyFunction()Советы и рекомендации по использованию
При использовании выражения profile учитывайте следующие советы и рекомендации:
Время, сообщаемое выражениями
profile, не является детерминированным для данного фрагмента кода. Фактическое измеренное время может как зависеть, так и не зависеть от многих факторов, которые вы не контролируете, таких как состояние игры, количество игроков, нагрузка на серверное оборудование, задержки в сети и многое другое. Рекомендуется оценить производительность фрагмента кода несколько раз, чтобы определить лучшее, среднее и худшее время, а также понять, какие точки данных являются случайными выбросами.На оценку производительности уходит не так много вычислительных ресурсов; в основном они тратятся на запись данных в журнал и интерполяцию строк пользовательских тегов. Это может немного увеличивать измеренное время, поэтому старайтесь оценивать производительность только интересующих вас фрагментов и используйте простые пользовательские теги.
Избегайте вложенности выражений
profile. Код будет работать, но затраты на оценку выполнения внутреннего выраженияprofileбудут учитываться во времени для внешнего выраженияprofile, что повлияет на итоговый результат.Удалите выражения
profileиз распространяемого кода игры. Генерация контрольно-проверочного кода не исключается из сборок для распространения, поэтому она будет вызывать нежелательное снижение производительности любого внутриигрового кода, если вы сохраните такие выражения.
Известные ограничения
Ниже перечислены известные ограничения использования выражения profile.
Вы можете использовать выражение profile в асинхронном контексте, но в блоке кода profile нельзя вызывать асинхронный код. Это демонстрируется следующим примером.
MyAsyncFunction()<suspends>:void=
profile: # Allowed inside <suspends> function
MyRandomInt := GetRandomInt(10, 100) # Allowed inside profile
Sleep(0.0) # Not allowed inside profileВы не можете использовать выражение profile при инициализации статичных данных членов class. Код в следующем примере недопустим.
my_class := class:
Value:int = profile{ 1 + 2 + 3 }