Unity:昂贵的方法调用和 null 比较昂贵 - 解决方案 (RIDER IDE)?
Unity: Expensive Method Invocation AND null comparison expensive - solutions (RIDER IDE)?
我收到 "Expensive Method Invocation" 和 "Null comparison expensive" 警告,我想知道如何解决这些问题。
void Update()
{
CheckCollision();
}
在 CheckCollison 中发生错误的地方,如下面的评论所示。
void CheckCollision()
{
var topHit = Physics2D.OverlapCircle(topCollision.position, 0.2f, playerLayer);
if (topHit != null) // ***<<<< NULL COMPARISON EXPENIVE!***
{
if (topHit.gameObject.CompareTag("Player"))
{
if (!stunned)
{
var rigidBodyTopHit = topHit.gameObject
.GetComponent<Rigidbody2D>(); // ***<<<< EXPENSIVE METHOD INVOCATION!***
rigidBodyTopHit.velocity = new Vector2(rigidBodyTopHit.velocity.x, 7f);
canMove = false;
_myBody.velocity = new Vector2(0,0);
_animator.Play("SnailStunned");
stunned = true;
}
}
}
if (!Physics2D.Raycast(downCollision.position, Vector2.down, 0.1f))
{
ChangeDirection();
}
}
这些不是警告,而是信息亮点。它们旨在通知您,您正在做一些已知代价高昂的事情,在性能敏感的上下文中(Update
方法),您可以在必要时重新评估您的方法.
"if necessary" 位很重要 - 只有您可以决定此 Update
方法的性能特征是否适合您的 game/application。如果这种情况发生在很少使用的选项屏幕中的单个游戏对象中,那么它很可能不是问题。但是如果它在一个被多次实例化并在核心游戏中使用的对象中,可能这些昂贵的方法会加起来并降低性能(或影响电池寿命)。
一般来说,编写没有任何这些信息亮点的代码可能会非常困难(而且没有必要),但是如果您发现您有很多代码有很多亮点,那么这是一个很好的迹象,你应该分析一下,看看你对结果是否满意。
您可以通过使用 Alt+Enter、展开检查选项项并选择 "Why is Rider/ReSharper suggesting this?" 项。这将打开一个网页,其中包含有关该特定亮点的更多详细信息。
This page also has an overview and more details,也可以在 首选项 | 中禁用检查。编辑|检查设置 |检查严重程度 | C# 设置页面(在 Unity | Performance indicators 下)。
查看代码示例中标记的项目,相等比较是昂贵的,因为它还检查底层引擎对象是否已被销毁,这意味着转换为本机代码。如果您知道该对象尚未被销毁(并且看到它是从 Unity API 返回的,我认为这是一个安全的选择),那么您可以将其替换为:
if (!Object.ReferenceEquals(topHit, null)) {
// …
}
但请记住,在您的用例中,这是一个可能不必要的微优化。
(用if (!topHit)
调用隐式bool
运算符与if (topHit != null)
、both operators call the private Object.CompareBaseObjects
method完全一样)
第二项是对 GetComponent
的调用,众所周知,这很昂贵,但在这种情况下是必要的。没关系 - 这只是信息性的,并不是告诉你做错了什么。
我收到 "Expensive Method Invocation" 和 "Null comparison expensive" 警告,我想知道如何解决这些问题。
void Update()
{
CheckCollision();
}
在 CheckCollison 中发生错误的地方,如下面的评论所示。
void CheckCollision()
{
var topHit = Physics2D.OverlapCircle(topCollision.position, 0.2f, playerLayer);
if (topHit != null) // ***<<<< NULL COMPARISON EXPENIVE!***
{
if (topHit.gameObject.CompareTag("Player"))
{
if (!stunned)
{
var rigidBodyTopHit = topHit.gameObject
.GetComponent<Rigidbody2D>(); // ***<<<< EXPENSIVE METHOD INVOCATION!***
rigidBodyTopHit.velocity = new Vector2(rigidBodyTopHit.velocity.x, 7f);
canMove = false;
_myBody.velocity = new Vector2(0,0);
_animator.Play("SnailStunned");
stunned = true;
}
}
}
if (!Physics2D.Raycast(downCollision.position, Vector2.down, 0.1f))
{
ChangeDirection();
}
}
这些不是警告,而是信息亮点。它们旨在通知您,您正在做一些已知代价高昂的事情,在性能敏感的上下文中(Update
方法),您可以在必要时重新评估您的方法.
"if necessary" 位很重要 - 只有您可以决定此 Update
方法的性能特征是否适合您的 game/application。如果这种情况发生在很少使用的选项屏幕中的单个游戏对象中,那么它很可能不是问题。但是如果它在一个被多次实例化并在核心游戏中使用的对象中,可能这些昂贵的方法会加起来并降低性能(或影响电池寿命)。
一般来说,编写没有任何这些信息亮点的代码可能会非常困难(而且没有必要),但是如果您发现您有很多代码有很多亮点,那么这是一个很好的迹象,你应该分析一下,看看你对结果是否满意。
您可以通过使用 Alt+Enter、展开检查选项项并选择 "Why is Rider/ReSharper suggesting this?" 项。这将打开一个网页,其中包含有关该特定亮点的更多详细信息。
This page also has an overview and more details,也可以在 首选项 | 中禁用检查。编辑|检查设置 |检查严重程度 | C# 设置页面(在 Unity | Performance indicators 下)。
查看代码示例中标记的项目,相等比较是昂贵的,因为它还检查底层引擎对象是否已被销毁,这意味着转换为本机代码。如果您知道该对象尚未被销毁(并且看到它是从 Unity API 返回的,我认为这是一个安全的选择),那么您可以将其替换为:
if (!Object.ReferenceEquals(topHit, null)) {
// …
}
但请记住,在您的用例中,这是一个可能不必要的微优化。
(用if (!topHit)
调用隐式bool
运算符与if (topHit != null)
、both operators call the private Object.CompareBaseObjects
method完全一样)
第二项是对 GetComponent
的调用,众所周知,这很昂贵,但在这种情况下是必要的。没关系 - 这只是信息性的,并不是告诉你做错了什么。