重用对象实例与在每次更新时创建新实例
Reusing instances of objects vs creating new ones with every update
每次我交换缓冲区时,重用对象实例与创建新实例之间有什么区别和陷阱?
背景:
这是我的一个游戏引擎项目。
我正在写一个 TripleBuffer,其中每个对象都有三个版本:旧版本、当前版本版本,以及未来版本。将通过从当前版本读取状态并将更改应用到未来版本来对这些对象进行更改。对所有对象进行更改后(分别在适用的情况下),缓冲区将被交换:未来对象成为当前对象,当前对象成为旧对象,旧对象对象?
- 要么被丢弃,新对象将通过遍历现在当前对象
分配
- 或成为现在未来的对象,它们的值将更新(resp。覆盖)通过遍历 now 当前对象。
说明:
- "reusing":用新值覆盖旧实例的值,有效地改变实例的状态
- "new ones/cloning": 使用旧实例的数据创建新实例,并对其应用更改
用例:
假设大约 1000 个对象以 30Hz 的频率交换,这意味着它们需要每秒重新创建 30 次,方法是克隆当前的对象或重新使用现在已过时的最后一个旧对象(覆盖所有状态)。
它们的复杂程度从大约 5 个属性到数百个属性不等,并且总是具有至少 2 个级别的深度。
(深度至少 2 级 = 缓冲对象本身将仅包含构成它们的其他唯一对象的映射)
重新创建和重用都需要迭代当前对象及其组件(短于:反过来组成它们的对象)。
进一步考虑:
在引擎的其他部分,将有事件触发和其他魔术,它们将使用对象的实时快照来工作。因此,重新创建或重用的决定将导致:
- 重新创建 意味着我可以安全地传递对对象的引用,因为对象在成为当前对象[=68=时将变得不可变]
- 重用 意味着我将不得不创建 当前对象 的副本或我进一步需要的任何部分,因为我不能保证事件(或其他)将在对象被重用之前被处理
除非您有充分的理由不这样做,否则请丢弃旧对象并创建新对象。
这将减少出现各种错误的几率。例如,如果在其他地方有对旧对象的引用,重新使用它可能会产生不良的副作用。丢弃和创建新对象在概念上更清晰,并且可能会使代码更易于阅读、调试和维护。
在一般情况下,垃圾收集器也足够聪明,可以使丢弃和重新创建对象的成本不那么高。
在这种情况下我会做的是编写最清晰、最直接的代码,这意味着在我需要时创建一个新对象。然后我会对其进行测试,看看这是否是性能瓶颈,如果是,我会考虑优化。换句话说,我会尽量避免premature optimization。
图形中使用了一个缓冲区,这样您在尝试更新它时就不会 "drawing" 逐个像素地查看屏幕。相反,您绘制到缓冲区,然后您可以一次交换整个图像。
我假设您使用缓冲区的原因与此类似。您不希望在处理 "current" 对象时使用新更新的对象进行修改,因为这会破坏当前对象的 "image"。
重用的优点:
- 您没有丢弃那么多内存,需要更少的垃圾收集
- 您只需更新已更改的对象
重新创建的优势
- 必须创建每个对象
- 更简单更干净
您的最终决定将基于性能与清晰度。重新创建所有对象的成本是多少?在每个对象之间进行比较并只构建需要的对象是否更便宜?
即使比较对象或跟踪已更改的对象的成本更低,但为了更简单而创建新对象的成本可能是值得的,这正是 的意义所在。
每次我交换缓冲区时,重用对象实例与创建新实例之间有什么区别和陷阱?
背景:
这是我的一个游戏引擎项目。
我正在写一个 TripleBuffer,其中每个对象都有三个版本:旧版本、当前版本版本,以及未来版本。将通过从当前版本读取状态并将更改应用到未来版本来对这些对象进行更改。对所有对象进行更改后(分别在适用的情况下),缓冲区将被交换:未来对象成为当前对象,当前对象成为旧对象,旧对象对象?
- 要么被丢弃,新对象将通过遍历现在当前对象 分配
- 或成为现在未来的对象,它们的值将更新(resp。覆盖)通过遍历 now 当前对象。
说明:
- "reusing":用新值覆盖旧实例的值,有效地改变实例的状态
- "new ones/cloning": 使用旧实例的数据创建新实例,并对其应用更改
用例:
假设大约 1000 个对象以 30Hz 的频率交换,这意味着它们需要每秒重新创建 30 次,方法是克隆当前的对象或重新使用现在已过时的最后一个旧对象(覆盖所有状态)。
它们的复杂程度从大约 5 个属性到数百个属性不等,并且总是具有至少 2 个级别的深度。
(深度至少 2 级 = 缓冲对象本身将仅包含构成它们的其他唯一对象的映射)
重新创建和重用都需要迭代当前对象及其组件(短于:反过来组成它们的对象)。
进一步考虑:
在引擎的其他部分,将有事件触发和其他魔术,它们将使用对象的实时快照来工作。因此,重新创建或重用的决定将导致:
- 重新创建 意味着我可以安全地传递对对象的引用,因为对象在成为当前对象[=68=时将变得不可变]
- 重用 意味着我将不得不创建 当前对象 的副本或我进一步需要的任何部分,因为我不能保证事件(或其他)将在对象被重用之前被处理
除非您有充分的理由不这样做,否则请丢弃旧对象并创建新对象。
这将减少出现各种错误的几率。例如,如果在其他地方有对旧对象的引用,重新使用它可能会产生不良的副作用。丢弃和创建新对象在概念上更清晰,并且可能会使代码更易于阅读、调试和维护。
在一般情况下,垃圾收集器也足够聪明,可以使丢弃和重新创建对象的成本不那么高。
在这种情况下我会做的是编写最清晰、最直接的代码,这意味着在我需要时创建一个新对象。然后我会对其进行测试,看看这是否是性能瓶颈,如果是,我会考虑优化。换句话说,我会尽量避免premature optimization。
图形中使用了一个缓冲区,这样您在尝试更新它时就不会 "drawing" 逐个像素地查看屏幕。相反,您绘制到缓冲区,然后您可以一次交换整个图像。
我假设您使用缓冲区的原因与此类似。您不希望在处理 "current" 对象时使用新更新的对象进行修改,因为这会破坏当前对象的 "image"。
重用的优点:
- 您没有丢弃那么多内存,需要更少的垃圾收集
- 您只需更新已更改的对象
重新创建的优势
- 必须创建每个对象
- 更简单更干净
您的最终决定将基于性能与清晰度。重新创建所有对象的成本是多少?在每个对象之间进行比较并只构建需要的对象是否更便宜?
即使比较对象或跟踪已更改的对象的成本更低,但为了更简单而创建新对象的成本可能是值得的,这正是