This article from 2015 10000 Update() calls says that one of the reasons for Update calls being expensive is them being calls from “unmanaged C++ land to managed C# land” (quote) which are represented by IL2CPP’s ScriptingInvocationNoArgs function but as far as I understand IL2CPP converts all C# code (including microsoft’s stripped standard libraries) to C++ code and there shouldn’t be a place for C++ to C# call, and even if the C++ code was accessing System’s standard libraries written in C#, the Update call isn’t one of them.
I am confused by this info, please tell me if I am wrong about it, or if the article is wrong about it, or if there’s a place for misunderstanding…
This can be a bit confusing. Even though IL2CPP converts the managed code (IL byte code, the output of the C# compiler) into C++ code, there is still a cost to call from C# (managed) to C++ (native) and back.
That cost occurs because of something called marshaling, with translates the C# (managed) world, where memory is managed by the garbage collector, to the C++ (native) world, where it is not.
The fact that IL2CPP uses C++ is really an implementation detail. IL2CPP still has to fulfill all of the requirements of a .NET runtime.
With that said, I’m unsure if the results of this blog post are still relevant. If this is a concern for you, I would recommend profiling on a recent version of Unity. A lot has changed in the implementation since 2015!