Is Instantiate bad for performance? Unity says it's fast, forums say it's slow...

Hey guys,

I am trying to optimize my game and I read on the forums that Instantiate can be bad for performance. But I never really had a problem using it because Unity themselves said here:
http://docs.unity3d.com/Documentation/ScriptReference/index.Instantiate.html
that:
"Instantiate is incredibly fast and very versatile. It is essential to using Unity to its fullest. "

So is it bad for performance or isn’t it? Unity also doesn’t include it in the section for script or graphical performance here:
http://docs.unity3d.com/Documentation/ScriptReference/index.Performance_Optimization.html
or here:

However on the forums (here) people tend to say it is bad for performance. So what’s the deal?
In my case my target is webPlayer and I use Instantiate for muzzleflashes and bullet marks.

Thanks!

Do you have any examples of people saying it’s bad for performance?

Sure, here for example (this person REALLY doesn’t recommend using it):

and here (“Instantiate and Destroy are heavy operations”):

It’s all about context. If you’re instantiating objects that are not common, the cost is fairly low overall. If you’re instantiating a bullet firing rapidly as in one of the example links - it’s going to add up frame for frame memory and performance wise.

Bottom line, use when you need it and be smart for when it’s not really required, example, instantiate object, add to pool and re-use as and when required

Of course if the game is really small or simple enough, keep gameobjects hidden until you need them, that way you already have them in the scene.

2 Likes

Thanks Univerb, by “objects that are not common” do you mean things which are not instantiated often? In this case, what about something like bullet marks in a multiplayer environment? there could be tens or eveb hundreds of them at any given time, is it better to pool such a huge number of prefabs?
EDIT: Sorry I misread your post, I see what you mean now :slight_smile:
But would you recommend pooling hundreds of prefabs? such as bullet marks?

check it out :

world is generated/destroyed on the go with instantiate/destroy functions, no lags.

5 Likes

I’m a firm believer in using a pooling system for objects that are instantiated and destroyed frequently.

In my initial set up, I had instantiate and destroy, then switched to pooling, and noticed substantial difference in performance, particularly on the iPhone 4/Touch 4. I have up to max 160 objects on screen at any one time plus bullets - so I do have a lot.

For your purposes, with bullet holes where you could potentially have 100s, I would definitely be pooling them.

3 Likes

Instantiate is awful mostly when used with destroy. It’s terrible for mobile. You won’t however notice anything if you’re making empty-world™ like the above misguided video.

You use instantiate to create copies to reuse from a pool. Don’t do it during gameplay for mobiles. If you do it once every few seconds you probably will not ever notice a problem. But if you do it often, ie once a frame, enemies spawning etc - you will notice a problem.

Basically, just use instantiate. If your game is slow, fix it by pooling.

14 Likes

Thanks OceanBlue and Hippocoder!

Take a look at plugin called poolmanager 2.0… I think it’s on the store… will make life easy for you.

1 Like

Thanks! Looks like a good tool, although in the meantime I created my own little system, just using and array of GameObjects which are used and recycled, using SetActve instead of Instantiate/Destroy.

Saw a small performance improvement :slight_smile:

Don’t forget to use profiler - that’ll tell you where the slowdown actually is. Mobile has a free version of it built in.

2 Likes

Well, I still think it depends on the usage and the platform…

I’ve recently used Instantiate for displaying some kinda ghost-version of the building/unit that get’s placed and destroyed it after I had no use for it. No performance issues and it’s like before when it’s destroyed. Still as a lot of units were instantiated for testing purposes, no performance issues. But this was only tested on PC Version.

So I think you have to look at different variables, like:

  • Which Platform? (PC works best ofc)
  • How many units/Objects?
  • How many of them are animated?
  • When do you instantiate them? Just one at a time but pretty often, many at once?
  • There might be more reasons :smile:

So if you notice performance issues, I would change the system or reduce the instantiate amount, like only instantiate 1 bullet or 10 and placing them beneath the map so it’s not visible. If you need that bullet just move it to the place it’s gonna needed. This will work for most stuff. (But also think about long loading times if you instantiate everything at beginning just to make use of them later on when u have to move something…)

Might be wrong on some parts, just my oppinion my 2 cents :slight_smile:

Thanks Hippocoder, will do that. I was actually just checking framerates. I assume Instantiate() will be under ‘scripts’? Am just wondering because there’s a lot running in the background with it (as opposed to ‘just’ a calculation).

Thanks SlyRipper! :slight_smile: I wil take that into account :smile:

Hi,
The problem with instantiate is that it takes CPU cycles, so, if you use a pool instead, you will save those. This practice cuts your app loading time and prevents performance spikes that can occur when objects get instantiated.
Destroy creates another problem. The memory occupied by the objects you destroy must be cleaned by the garbage collector. It can happen anytime and it will create a performance spike.
So, using instantiate and destroy, is not a good idea at 99% of the cases. I do not know where they are useful actually, but they must be useful somewhere since they exist. Try to use pooling instead.

Great point. The only situation I can think of would be…if memory is scarce, and cpu/framerate is not.

Thanks Ippokratis and jc_lvngstn!

The pooling plugins use Instantiate to create the items in the pools in fact when the scene is loaded. I know, because I use that code in my Master Audio plugin. Also saw similar code in Pool Manager.

I agree, always pool if you can. It prevents a lot of sudden jittery garbage collection moments on mobile devices. Absolutely essential!

We created PoolManager because we had trouble with both sides of the equation; instantiate and destroy.

Instantiate shows up on the profiler and seems to do so more the first time. We assume this is because Unity has to load dependencies in to memory the first time. This is why we also added preloading; to instantiate as many instances as possible when a game/level/prefab loads so we can design pool loading so it doesn’t happen during game-play.

Avoiding destroy was the bigger issue for us though. The garbage collection was causing stutters after awhile. It took us a while to track it down because it seemed pretty random and required a lot of variables to come together to make it happen. We couldn’t even reproduce it reliably. Once we started pooling it went away. We even added a mechanism for destroying pool items over time just in case there is a big event that overfills the pools so they could be reduced back to normal levels automatically. This reduced the destroy calls to rare cases where memory is critical (seems quite rare though).