Destroying and creating objects vs keeping an array in memory

Assuming that you’re creating an infinite platformer where you’re constantly throwing obstacles at the player, how beneficial is it to keep an array of objects in memory that get recycled instead of destroying and creating from a random array?

I do understand that keeping a limited amount of already created elements in memory reduces workload and results in a lighter game, but it also means that the generation isn’t truly random and for a game that’s simply creating basic objects, how much of an advantage does that really provide over constantly destroying and creating obstacles?

I might actually contest that point. If you make a scene with 10,000 objects pre-loaded, it’s probably going to run worse than if you procedurally spawn and destroy objects to keep 100 or so loaded at a time. From infinite projects I’ve done, I’ve always destroyed and instantiated objects with no issues; this helps keep the loaded number of objects to a minimum.

Also, you can’t make the level truly infinite unless you do spawn and destroy objects as the played moves thru it.

Surely pooling doesn’t limit the randomness, can’t you just re position the recycled object as you would have if it was you? And you don’t need 10000 objects ever, say you have 10 pieces of level on screen at once using the same base, you only need 10 objects pooled

Or am I missing something here?

My understanding of whether to use instantiation vs pooling comes down more to how often you instantiate and destroy instead of how many variations of objects you instantiate. If you’re instantiating an object every few seconds you’re not going to see much of an improvement from pooling. If you’re instantiating far more frequently though, then pooling should be something you’re looking at.

2 Likes

I usually shy away from premature optimisation but having released an endless runner and helped several customers with there’s this is a case where I’d just jump straight to the optimisation (i.e. pooling).

Even when you aren’t instantiating frequently (and most runners are going to be exposing numerous objects per second) there is another cost to instantiating/destroying … random CPU spikes (due to GC, delayed cost of removing objects, etc).

A pooling implementation is barely more complex than directly instantiating.

EDIT - Obligatory plug:
https://www.youtube.com/watch?v=HNoTytvjJSc

(no longer available on iOS but you can still get it in on Android)

1 Like

Well, no, you’re never going to have an infinite number of different objects. Just spawn a minimum number that you’d need and reuse/reposition them as necessary. If you ever need more than that, you’d simply spawn them on the fly and add to the pool, which would be a basic feature of a pooling system anyway. No need to pre-load 10K objects. You also wouldn’t keep the unused objects active. There wouldn’t be any limitations regarding randomness, and only upsides with no real downsides, other than (as mentioned above) slightly increased complexity. Unless every object you create is actually unique, I see no reason not to use pooling.

–Eric

2 Likes

Apologies for the late reply.

How big were the objects on said projects?

How so? You can just keep reusing the same objects once they leave the screen.

The problem I have is: Assume there are 3 possible types of platforms that can appear, if I have a pool of 3 of each there’s a limit of 3 of each that can be on screen at a time, unless the pool is large enough to always have enough of each type to use it won’t be truly random.

This is exactly what I’m trying to understand, when does pooling become a viable option when compared to instantiation? How many objects need to be spawned per second in order for it to be memory inefficient?

From what I see your game has at most 2 types of platforms at a time, did you keep a finite amount of platforms pooled? Did you use any sort of control as to when a platform can spawn to avoid running out of objects?

Is constantly activating and deactivating objects a “cheap” operation?

There are 5 types of platforms per scenario and they can be all on screen at same time (normal, falling, rising, spiked, sticky, ice). There are ~15 types of objects. There’s no explicit rules around platform spawn limits, although implicitly the rules which drive the game would define some implicit limit.

We pre-populated a pool but if a request is made to an exhausted pool it creates a new object and adds it to the pool. This is mainly for testing, during play-testing we tweaked pool size such that such situation never occurs (not that an occasional instantiation matters).

Keep in mind that a pool of a few hundred or even a few thousands objects is a barely a blip on the radar performance wise.

Unity is notoriously slow to instantiate objects, so yeah, if you’re using more than just a few things that aren’t already in the scene you should pool them, especially things constantly spawned. However, Unity’s upcoming Job System in 2018.1 supposedly fixes that issue - they showed it instantiating something like 60,000 objects at once without any hitches.

Why don’t you just create more objects for the pool if needed? You don’t need to pre-populate it at all although pre-populating with an expected amount is sensible.