As our project grows we’re experiencing higher and higher overhead on the compile and going-into-play-mode actions. I’ve been doing some marginal profiles and testing recently to try and narrow down on the culprits. I did manage to get going-into-play-mode time down quite a bit, but I feel there should be more room for improvement.
For reference, it takes me between 7-8 seconds to go into play mode with:
i7 6700k
32GB RAM
M.2 1400MB/s SSD
GTX 970 (largely irrelevant for this I assume)
I also have a laptop, which takes around 10 seconds to go into play mode with:
i7-7700HQ
16GB RAM
SSD
GTX 1070MQ
There are a few things in the profiler that I am not sure I understand. Let’s start with a non-deep profile on the laptop:
This is the first thing that caught my eye when profiling - a big chunk (~5) of the first 9 seconds are spent in ReloadAssembly (1/4th of which is in executing the OnLoadAttribute)
To get more info let’s look at the deep profile:
The first strange thing on this snapshot is that the [Time ms] are not shown in the majority of the stack trace. I assume that’s either a limitation of the profiler or a bug. In either case, that’s not terribly useful as an absolute metric in deep profile - it’s mainly useful to locate the bottleneck. I used the GC Aloc instead, which works in this case.
Looking at this stack trace I also feel a bit worried - you can see CreateDefaultEncoding() opening a FileStream, which eventually loads in all Editor Assemblies. Let’s not go into that though - just looking at the bottleneck, it seems that RegisterAssembly() is really what eventually ends up eating a lot of that time (by using some good-old reflection) since it’s called 331 times.
This is no surprise, but I am trying to make things run faster, so I ask if anyone has any ideas on how to improve this situation? For instance, why is the profile detecting 2 calls to AssemblyUtilities.Reload()? I put a breakpoint in that method and was able to extract a list of all of our assemblies, a total of 166 - this number seems quite high, this is how they are spread out:
- 42% - UnityEngine
- 9% - UnityEditor
- 49% - Other
Even though the numbers here are pretty high (50% of all of the assemblies are Unity’s - about 85 in total), you would think that going-into-play-mode in an empty project will have a similar overhead in the same path - but no, I don’t even see that path on the profiler when I run it on one of my minimal demo projects:
The [Time ms] looks similar, but the cause seems to be different. I can’t tell if that’s a bug in the profiler showing me the same thing or I am missing something obvious.
Am I going crazy here? I am just trying to find a way to iterate faster while in the editor.