0
\$\begingroup\$
  • Re-using pre-instantiated objects in a pool.
  • Destroying then re-instantiating objects in a pool.

Both pools are limited.

When creating loads of objects which is better for performance?

\$\endgroup\$
2
  • 2
    \$\begingroup\$ I'm not sure I understand your question. The whole point of pooling is to improve performance. If you're destroying and re-instantiating, you are not pooling. Can you clarify where exactly your point of confusion is here? \$\endgroup\$
    – DMGregory
    Apr 25, 2020 at 19:22
  • \$\begingroup\$ I think that is the answer to my question. <Re-instantiating is not pooling>, so I have to re-use stuff If I want to call it pooling. \$\endgroup\$ Apr 26, 2020 at 9:36

1 Answer 1

3
\$\begingroup\$

When you instantiate a new object, a whole bunch of stuff needs to happen:

  • The engine has to allocate memory to hold its native/unmanaged representation (the guts of the object inside the engine itself)

  • The .Net runtime has to allocate memory to hold its managed representation (the parts visible to your C# scripts, and any C#-based components), and register them with the garbage collector (GC alloc)

  • The new objects need to be constructed in that allocated memory.

  • The deserializer has to copy the data from the prefab you're instantiating into this new memory space, and wire-up any internal references between objects/components in the new copy.

  • The new object needs to be added into the engine's various update lists for scripting callbacks, physics, rendering, etc.

  • Components' Awake, OnEnable, and Start methods need to be run.

This takes time. Not a lot individually, but it adds up. When you Destroy an object, all this work needs to be undone, and that takes time too.

The "GC alloc" bit also means you're using up some of your garbage collection headroom. Once you run out, the runtime puts your scripts on hold to do a full mark & sweep pass and clear out any unused objects, and compact the used memory to free up space. This can cause a noticeable hitch in your framerate, so it's best if we don't trigger the garbage collector too frequently in the thick of play.

When you keep objects in a pool, deactivate them instead of destroying them, and re-activate them to recycle them instead of spawning new ones, you get to skip doing almost all of this work, and you create no new work for the garbage collector.

So pooling/recycling is definitely more efficient than instantiating/destroying, for objects that you're spawning & despawning frequently. Don't worry about it for objects you spawn only a handful of times in your level, but things like bullets or particle effects that you use by the dozens or hundreds, that might spawn & despawn every few seconds, are prime candidates for this kind of optimization - especially if you're targeting mobile.

\$\endgroup\$
2
  • \$\begingroup\$ I got another related question: When is it required to call Destroy on an object then? Or is it better to just de-activate it? Is it better to let it sit in memory or just destroy it if it will never be used again? I'm imagining for instance a Tank prefab, which isn't going to be used a lot, so it seems to be a Destroy case, but if the player spams the Tanks then it becomes more of a Pool case. \$\endgroup\$ Apr 26, 2020 at 19:50
  • 1
    \$\begingroup\$ It sounds like you already understand it: if you're going to use it again, don't destroy it. If you're not going to use it again, it's safe to destroy. \$\endgroup\$
    – DMGregory
    Apr 26, 2020 at 19:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .