С помощью выражения 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 }