Doesn't the C# JIT inline property getters in Unity?

I’ve been working on a grid-based game and ran into a performance problem. Iterating over thousands of grid nodes caused noticeable lag and the profiler showed that my property getters we’re the source of all evil.

public int xSize { get; set; } // 130 ms
public int xSize; // 30 ms

The profiler reported 130 ms for all calls of the backing field via get_xSize. I changed it to a public field and the time went down to 30 ms. That’s more than 20% speed improvement only because of a simple getter.

How can this be? I thought that property getters are inlined by the JIT, but apparently this is not true, at least when testing with the Profiler in the Unity editor. Or might the test scenario be the problem and they are inlined in non-debug build?

1 Like

After some profiler sessions with the editor, debug builds and builds I have come to the conclusion, that the inline process only happens for builds, but it does work correctly.

Running my example with fields instead of properties in the editor would be twice as fast, but once I ran a build with the same setup, there was not noticeable difference. I did have to construct some rather artificial testcase to actually see the results, since the profiler doesn’t show the same level of detail when profiling builds, but still I could see that there was no real change.

I assume that this behaviour has something to do with the ability to set breakpoints in properties, but I don’t really know. Anyway, good to know that I have 50% headroom when everything is a property. xD

JIT Inlining happens only in Release time as the name implies. It’s supposed to be off in debug mode not only in Unity but also 3rd party IDE’s such as Visual Studios because code optimization can scramble your written code and make it hard to catch errors.

Usually in C# Visual Studio there is an option to turn on Code Optimization in the Project Properties section. Doing so can decrease debug run time dramatically. However in Unity the Visual Studio Project Properties is off-limits by default and even if you can break into it and turn Code Optimization on, Unity will override those properties and you will see no changes.

I prefer to turn Code Optimization on when testing for performance so this is a little disappointing for me. I’m still searching for a way, but there is no drastic performance issues with getters and setters in Release builds. JIT Optimization along with Inlining is still intact.

Reading this would suggest that no getters are not inlined:

Doc Link

"The primary issue here is that Unity performs very little method inlining, if any. Even under IL2CPP
, many methods do not currently inline properly. This is especially true of properties. Further, virtual and interface methods cannot be inlined at all.

Therefore, a method call declared in the source C# is very likely to end up producing a method call in the final binary application."