It's worth mentioning that there's now a third way C# is utilised in Unity which is via their new 'Burst' compiler, part of their wider move to an Entity Component System they've called DOTS[1]. It supports a subset of C# that gets compiled into memory safe jobs that can run safely on and spread across different threads. I'm using the Burst compiler + jobs in my full-time game project and the performance is seriously good for whenever you just need to process a lot of data. You can use Burst with both Mono and IL2CPP script modes.
The go-to deep dive on how DOTS/Burst works is pretty much everything Jackson Dunstan has ever written on the matter [2] but specifically the article that digs into how IL2CPP calls Burst is interesting.[3]
[1] - https://docs.unity3d.com/Packages/com.unity.entities@0.17/ma...