- Home /
Hiccups, simple lines of code sometimes taking several milliseconds
So I've been looking at this for the past 2 days and I just can't figure it out.
The problem is that I'm getting FPS drops every second or every few seconds. They don't show up well in the profiler, so I resorted to adding Stopwatches to the code. I'm getting weird results, both in the Editor and in a Windows standalone build.
The code below is called from within a Unity coroutine, literally copy & pasted, no modifications:
var stopwatch = new Stopwatch();
stopwatch.Start();
var go = new GameObject();
var elapsed = stopwatch.ElapsedMilliseconds;
if (elapsed > 2)
{
Debug.Log("new GameObject took " + elapsed + "ms");
}
This actually triggers sometimes. Log shows "new GameObject took 4ms". And not only this statement, but other similiarly extremely simple statements that I surround with a Stopwatch. It seems random.
What it LOOKS like is that the main thread is somehow freezing or locking up. How is this possible? In a Unity coroutine, there shouldn't be ANYTHING else going on right? Garbage Collection, Physics, Rendering, other Coroutines etc. should be running either before or after?
And again it's not just 'new GameObject', other statements also take several milliseconds sometimes.
We've also tried disabled the Garbage Collector (see: https://forum.unity3d.com/threads/how-to-disable-the-garbage-collector-on-windows.369015/). Does not seem to make a difference, in both cases the weird freezes seem to happen.
Edit: extra information that could be relevant. We do create a TON of GameObjects, like in the order of 1000 per second. It's a big open world that uses a lot of procedurally generated models. Yes, we use tricks like manual batching to try and reduce the amount as much as possible, but we often need the actual individual gameobjects to exist independently.
Answer by FlaSh-G · Jun 21, 2017 at 10:05 AM
You assumptions are all correct as far as I can tell. But perhaps it's not accurate to run a stopwatch over a single line of code. I ran my Bencher over new GameObject()
and got results between 3 and 3.8µs. So even though it is rightfully discouraged to prefer instantiating and destroying over proper object pooing, a "new GameObject" line every now and then shouldn't be the cause of your problem.
Thanks for your response. I feel I should mention, we do create a TON of GameObjects, like in the order of 1000 per second. It's a big open world application that uses a lot of procedurally generated models. Aside from discussing whether or not we should do this (yes, we batch to try and reduce the amount as much as possible, but we often need the actual individual gameobjects to exist independently), is this likely a limitation of Unity? A thousand GOs per second causes hidden problems under the hood?
I don't have too much hard data, but object pooling is generally advised. Be careful with SetActive though, it's not the most performant thing either. I'd personally be interested in implementing a pooling solution myself if I were in your situation, but there are also some polling solutions in the Asset Store.