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.

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.