Tae*_*lia 8 c# getter performance xna new-operator
我有以下代码:
public class Character
{
public Vector2 WorldPixelPosition
{
get { return Movement.Position; }
}
public Vector2 WorldPosition
{
get { return new Vector2(Movement.Position.X / Tile.Width, Movement.Position.Y / Tile.Height); }
}
public Vector2 LevelPosition
{
get { return new Vector2(WorldPosition.X % Level.Width, WorldPosition.Y % Level.Height); }
}
}
Run Code Online (Sandbox Code Playgroud)
现在在我的代码中的其他地方,我在循环中对Character.LevelPosition进行了大约2500次调用.这意味着每个更新周期,5000'新'Vector2正在制作,而在我的笔记本电脑上,它确实降低了帧速率.
我通过创建暂时修复了它
var levelPosition = Character.LevelPosition;
Run Code Online (Sandbox Code Playgroud)
在我启动循环之前,但是每次遇到类似的情况时,我都会感觉到它的丑陋代码.也许它是 - 要走的路,但我想确定一下.
有没有更好或普遍接受的方式来做到这一点?
我正在使用XNA-Framework,它使用Vector2
的是.
根据我的理解,你应该避免在XNA中从堆中分配大量对象,因为这会导致性能不佳.但是既然Vector2
是a struct
,我们在这里没有在堆上分配任何东西,所以这不应该是问题.
现在,如果你像一个紧凑的循环一样,在一个性能关键的应用程序中,比如一个游戏,你将始终不得不考虑性能,没有解决这个问题.
如果我们查看代码LevelPosition
,你可以调用getter WorldPosition
两次,可能还有一些getter.吸气剂WorldPosition
可能会召唤其他几个吸气剂.(如果没有源代码,很难说究竟发生了什么,因为getter调用和字段访问看起来完全一样.)
调用getter(实际上只是对特殊方法的调用)通常非常快,如果编译器决定使用内联,则可以更快.但是所有的调用都加在一起,特别是如果你在一个循环中调用它们.
解决方案是某种缓存.一种选择是创建LevelPosition
一个字段并设计一个系统以在必要时更新它.这可能会有效,但如果你需要比你读它更频繁地更新它,它实际上也可能会损害性能.
正如您所发现的,另一种解决方案是将结果缓存在局部变量中.如果你知道这是正确的,即在执行循环期间属性的值不会改变,那就太棒了!您解决了性能问题,只需使用一行代码即可让任何程序员轻松理解.你还想要什么?
让我重申一下.您找到了解决性能问题的解决方案:
我认为这样的解决方案很难被击败.