【发布时间】:2015-04-29 15:12:03
【问题描述】:
每次我交换缓冲区时,重用对象实例与创建新实例之间有什么区别和陷阱?
背景:
这是我的一个游戏引擎项目。
我正在编写一个 TripleBuffer,其中每个对象都有三个版本:旧版本、当前版本和未来版本。这些对象的更改将通过从当前版本读取状态并将更改应用于未来版本来进行。在对所有对象(分别在适用的情况下)进行更改后,缓冲区将交换:未来对象变为当前对象,当前对象变为旧对象,而旧对象?
- 要么被丢弃,并且将通过迭代现在当前对象来分配新对象
- or 成为 now 未来的对象,它们的值将通过迭代 now 来更新(分别覆盖)当前对象。
解释:
- “重用”:用新值覆盖旧实例的值,有效地改变实例的状态
- “新实例/克隆”:使用旧实例的数据创建新实例,并对其应用更改
用例:
假设大约 1000 个对象以 30Hz 的频率进行交换,这意味着它们需要通过克隆当前的对象或重用现在已过时的最后旧对象(覆盖它们的所有状态)每秒重新创建 30 次。
它们的复杂程度可以从大约 5 个属性到数百个属性不等,并且总是具有 至少 2 个级别的深度。
(至少 2 个级别的深度 = 缓冲对象本身将仅包含构成它们的其他唯一对象的映射)
重新创建和重用都将要求迭代当前对象及其组件(短于:依次构成它们的对象)。
进一步考虑:
在引擎的其他部分,将使用对象的实时快照来触发事件和其他魔法。因此,重新创建或重用的决定将导致:
- 重新创建意味着我可以安全地传递对对象的引用,因为对象在成为当前对象时将变得不可变
- reusing 意味着我必须创建 当前对象 的副本或我进一步需要的任何部分,因为我不能保证事件(或其他)会在之前得到处理对象被重用
【问题讨论】:
-
您一次要处理多少个对象?创建的成本是多少(比如它们有多少属性......初始化构造函数需要多长时间,它们将“有效”多长时间 - 即更新它们的频率)?....一般来说,我建议避免“重复使用”,除非它们是不可变的...... b/c 你有数据损坏的风险......你是否想提出垃圾收集策略?
-
编写“性能良好”的代码通常是件好事;但请记住:除非您谈论的是时间要求严格的高性能计算应用程序......不要担心性能。相反:尝试编写易于理解和维护的代码。从这个意义上说:如果对象是不可变的(它们的内部状态在创建后是“固定的”);例如,您可以避免许多有关线程安全的问题。因此,我倾向于避免“重用”任何东西;除非您在这里谈论数百万个对象。