向代码添加性能分析器标记,以便在 Profiler 窗口中的 CPU 使用情况模块的时间轴视图和层级视图中查看 ProfilerMarker.Begin、ProfilerMarker.End 或 ProfilerMarker.Auto 生成的样本:
一些示例会用到 Profiling Core 包,在开始之前必须安装该包。因为 Unity Profiling Core 是核心包,所以在 Package Manager__ UI__(即用户界面,User Interface)让用户能够与您的应用程序进行交互。Unity 目前支持三种 UI 系统。更多信息
See in Glossary 中无法找到。要安装包,请执行以下操作之一:
要使用 ProfilerMarker API,请将要分析的代码放在对 ProfilerMarker.Begin 和 ProfilerMarker.End 的调用之间。例如:
using UnityEngine;
using Unity.Profiling;
public class ProfilerMarkerExample
{
static readonly ProfilerMarker k_MyCodeMarker = new ProfilerMarker("My Code");
void Update() {
k_MyCodeMarker.Begin();
Debug.Log("This code is being profiled");
k_MyCodeMarker.End();
}
}
注意:避免在性能分析器标记的名称中使用 / 字符,因为这会使 Profiler 窗口无法在 CPU 性能分析器模块的图表视图中突出显示该标记。
确保在调用 End 之前,Begin 和 End 调用之间的代码不会退出作用域。如果在调用 End 之前代码退出作用域,则系统会将错误消息记录到控制台。为了避免在每次返回之前都必须调用 End,可以使用 Auto,这样样本在离开作用域时会自动结束。有关更多信息,请参阅本文档中关于自动关闭性能分析器标记代码块的部分。
Unity 会记录性能分析代码块的执行时间并将其报告给性能分析器,并将其显示在 CPU 性能分析器模块中,而无需使用深度性能分析。它将在 CPU 性能分析器模块的层级视图中显示为新条目,如下所示:
使用 ProfilerMarker.Auto 可确保在代码块末尾自动调用 ProfilerMarker.End。以下是等效调用:
using Unity.Profiling;
public class MySystemClass
{
static readonly ProfilerMarker k_UpdatePerfMarker = new ProfilerMarker("MySystem.Update");
public void Update()
{
k_UpdatePerfMarker.Begin();
// ...
k_UpdatePerfMarker.End();
using (k_UpdatePerfMarker.Auto())
{
// ...
}
}
}
与 Begin() 和 End() 调用不同,Unity 无法在非开发(发布)构建中编译排除 ProfilerMarker.Auto 调用。但是,它将返回 null,这样只会增加很少的开销。
还可以将 ProfilerMarker.Auto 与 using var 结合使用,一旦当前作用域结束,End 调用将自动发生。此方法可最大限度减少向代码添加 ProfilerMarker 实例时需要更改的代码量:
using Unity.Profiling;
public class MySystemClass
{
static readonly ProfilerMarker k_UpdatePerfMarker = new ProfilerMarker("MySystem.Update");
public void Update()
{
using var _ = k_UpdatePerfMarker.Auto();
// ...
}
}
注意:在使用 ProfilerMarker 进行标记的区域内不支持任何异步 await 和 yield 调用,即使使用 Auto,也会在控制台中记录错误消息。
有时,您可能希望向代码样本添加上下文,以确定代码长时间运行的特定条件。
例如,如果系统执行对象模拟,可使用性能分析器样本来传递对象的数量。如果性能分析器返回异常数值,且样本持续时间较长,这可能意味需要使用另一个线程进行模拟,将 CPU 工作拆分为多个帧(时间切片),或者调整应用程序的设计以避免掉帧。
ProfilerMarker 最多支持三个数字参数:ProfilerMarker<TP1>、ProfilerMarker<TP1, TP2> 和 ProfilerMarker<TP1, TP2, TP3>:
using Unity.Profiling;
public class MySystemClass
{
static readonly ProfilerMarker<int> k_PreparePerfMarker = new ProfilerMarker<int>("MySystem.Prepare", "Objects Count");
static readonly ProfilerMarker<float> k_SimulatePerfMarker = new ProfilerMarker<float>(ProfilerCategory.Scripts, "MySystem.Simulate", "Objects Density");
public void Update(int objectsCount)
{
k_PreparePerfMarker.Begin(objectsCount);
// ...
k_PreparePerfMarker.End();
using (k_SimulatePerfMarker.Auto(objectsCount * 1.0f))
{
// ...
}
}
}
ProfilerMarker API 支持将字符串参数添加到性能分析器标记中。如果要在应用程序加载关卡或数据文件时显示关卡或文件的名称,字符串参数会很有用。使用 ProfilerMarkerExtension 方法将字符串参数与性能分析器样本一起传递:
using Unity.Profiling;
public class MySystemClass
{
static readonly ProfilerMarker k_PreparePerfMarker = new ProfilerMarker("MySystem.Prepare");
public void Prepare(string path)
{
k_PreparePerfMarker.Begin(path);
// ...
k_PreparePerfMarker.End();
}
}