1

人们经常说我应该在一般情况下重用短期对象,但我不知道 XNA 就是这种情况。有物品、粒子和 NPC 是最常见的游戏对象,它们应该在某种池中重复使用还是从更新列表中删除并替换为新实例?这对性能有影响吗?

4

2 回答 2

3

以我的经验,这取决于它是否是一个 xbox 360 项目。如今,Xbox 360 将无法像通常的 PC 那样处理。当垃圾收集开始时尤其如此。

http://zfs.fzi.de/attachments/article/160/XNA_Optimization.pdf

请注意,此 pdf 中的第一个“要考虑的事情”是 xbox 360 垃圾收集。xbox 360 垃圾收集时间将随着每个对象的创建而线性增加。

于 2012-09-15T23:21:01.310 回答
3

在特定情况下,池化非常重要。也就是说,在您需要大量创建和处理常见对象(如子弹或体素实例)的情况下,它几乎总是有益的。

垃圾收集器很好,但它并不总是你的朋友。如果你像我一样构建一个使用数千个立方体来渲染地形和物体的游戏,你会很快注意到这一点(尽管我们花了几个星期才意识到确实是 GC 导致了我们的减速)。作为托管语言的程序员,我们习惯于简单地取消引用一个对象并让它被 GC 神奇地扫走。但事实是,当这些对象达到数千个时,GC 会超时工作。您会注意到每分钟左右都会显着放缓,具体取决于。

因此,与其不断地实例化和取消引用您的公共对象,不如使用静态的、大小稳定的对象池对 GC 造成的压力要小得多。

  • 静态:所有对象都被一次实例化,并且在运行时不会被取消引用以被 GC 拾取
  • 稳定大小:池中对象实例的数量不会经常变化(防止实例化性能下降)

这一切背后的原因是,在基本意义上,GC 必须在您之后清理您在游戏期间取消引用的每个对象中包含的所有引用。因此,如果您的块引用了相邻块,则必须检查它是否是对另一个块的唯一引用,因为如果是这样,那么另一个块现在也被代理取消引用(再次,非常简单的观点,但这是我学到的)。

通过创建一个池并简单地重用实例而不是丢弃它们,当您处理完其中一个对象时,您永远不会从 GC 触发此行为,因此您不必担心它会对数千或数百个对象进行大量检查随意创建和销毁对象。

我想说,基本上,你会知道什么时候需要汇集。您会定期遇到无法解释的减速,这似乎与您在游戏中执行的操作无关。这是 GC 在幕后为你做的清理工作。

于 2012-09-18T20:16:24.133 回答