人们常说一般来说我应该重用短期对象,但我不知道 XNA 是否属于这种情况。元素、粒子和 NPC 是最常见的游戏对象,它们应该在某种池中重复使用,还是只是从更新列表中删除并替换为新实例?这对性能有影响吗?
最佳答案
池化在特定情况下非常重要。也就是说,在需要大量创建和处理常见对象(例如项目符号或体素实例)的情况下,它几乎总是有益的。
垃圾收集器很不错,但它并不总是你的 friend 。如果你像我一样构建一个使用数千个立方体来渲染地形和物体的游戏,你会很快注意到这一点(尽管我们花了几周时间才意识到确实是 GC 导致了我们的速度下降)。作为托管语言的程序员,我们习惯于简单地取消引用一个对象,然后让 GC 神奇地将其清除。但事实是,当这些对象达到数千个时,GC 就会加类。视情况而定,您会每分钟左右注意到速度显着下降。
因此,与其不断地实例化和取消引用您的公共(public)对象,不如使用静态的、大小稳定的对象池来减轻 GC 的压力。
- 静态:所有对象都立即实例化,不会在运行时取消引用以供 GC 拾取
- stable-sized:池中对象实例的数量不会经常变化(防止实例化导致性能下降)
所有这一切背后的原因是,从基本意义上讲,GC 必须在您清理您在游戏中取消引用的每个对象中包含的所有引用。所以,如果你的 block 有一个相邻 block 的引用,它必须检查它是否是对另一个 block 的唯一引用,因为如果是这样,那么另一个 block 现在也被代理取消引用(再次,非常简单的观点,但这就是我学到的)。
通过创建一个池并简单地重用实例而不是丢弃它们,当您处理完其中一个对象时,您永远不会从 GC 触发此行为,因此您不必担心它会对数千个对象进行大量检查或数以百计的对象,您可以随意创建和销毁它们。
我会说,基本上,您会知道何时需要池化。您会定期遇到无法解释的减速,这似乎与您在游戏中执行的操作无关。这是 GC 在后台为您进行清理。
关于c# - 在 XNA 中重用游戏对象是否有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12442630/