代码检查:方法调用开销较大
性能关键上下文
Unity 事件函数 Update、 LateUpdate和 FixedUpdate被非常频繁地调用,要么每帧一次,要么足够频繁以匹配固定帧率。 同样,以协同程序方式调用的方法可以在每帧被挂起和恢复。 很明显,这些方法会影响游戏的性能,因此需注意并尽量避免在这些方法及其调用的方法中执行开销较大的操作。
JetBrains Rider 会通过编辑器装订区域中的行标记,高亮显示这些被频繁调用的方法以及它们调用的每个方法。 这些方法被视为 性能关键上下文。 在此上下文中,JetBrains Rider 会添加 性能指示器 ,以高亮显示开销较大的方法和操作。
这些高亮显示 不是传统检查 ,如警告或建议——代码并非“错误”,而是执行了已知开销较大的操作,避免这种代码模式有利于提升游戏性能。 通常,这些高亮显示没有简单的机械修复方法,避免这些操作通常需要更大工作量,比如重写甚至重新架构。 本质上,这些性能指示器只是为了提醒当前存在开销较大的操作。 是否要避免这些操作以及如何避免,取决于你的决定。
需要注意的是,这些性能指示器不能替代性能分析。 虽然某个操作可能被高亮显示为开销较大,但当前代码的性能也有可能已经足够好。 切记三思而后行!
开销较大的操作
JetBrains Rider 会在性能关键上下文中高亮显示各种众所周知的开销较大的操作:
调用
AddComponent方法调用
查找方法调用
GetComponent方法调用
Debug.Log方法基于字符串的方法调用
Camera.main属性的用法使用
null比较 Unity 对象
如果一个方法包含上述开销较大的操作之一,它本身也会被标记为开销较大,并会将此标记传递回原始调用方法。 换句话说,如果某方法包含开销较大的操作,或者调用了包含开销较大操作的方法,JetBrains Rider 会将该方法高亮显示为开销较大的操作。 例如:
那么所有方法, 更新、 DoSomething 和 DoSomethingExpensive 都会被标记为性能关键上下文,并在编辑器装订区域显示标记。 对 GetComponent 的调用被标记为开销较大的操作,并将此信息传递回原始调用方。 所以对 DoSomethingExpensive 的调用被标记为开销较大的操作,最后对 DoSomething 的调用也会被标记为开销较大。
请注意,即使 API 调用被已包装在 if 代码块中,仍然会被标记为开销较大。 在编辑时无法知道 if 语句的某个分支被调用的可能性。 可能 if 在对象生命周期内只调用一次,也有可能调用次数占 50% ,甚至每次都会调用。 这也是这些高亮显示只是信息型提示而不是警告的另一原因——此代码并非错误,而是为了提醒此 API 调用开销较大。
传播的上下文
JetBrains Rider 会将性能关键上下文传递到如 更新 和 FixedUpdate 等根方法中调用的方法。 这些方法也被视为性能关键上下文,会高亮显示开销较大的方法,并将该上下文继续传递给被调用的方法。 如果性能关键上下文中的任一方法调用了开销较大的 API,该方法也会被视为开销较大,并会将此标记传递回原始方法。 因此,如果 更新 函数调用的任何嵌套方法使用了开销较大的 API,这个函数也会将方法高亮显示为开销较大的操作。
如果发现某个方法被标记为“频繁调用”,可以在 Alt+Enter 菜单中的 Incoming Calls 操作中使用。 这可以查看是谁调用了该方法,并可向上遍历调用树,寻找根 更新 或其他频繁调用的方法。
请注意,此功能基于调用跟踪,可以带来非常智能且出人意料的结果。 例如,如果某方法作为委托或 操作 传递给其他方法并在其中被调用,也会被标记为频繁调用。
禁用性能检查
可以在 中单独禁用开销较大方法的高亮显示,也可以在 中禁用所有性能检查或性能指示器的装订区域行标记。 你还可以在 中编辑这些高亮显示的颜色。