Lessons in this course (11)

3. Compilation: Roslyn, IL, JIT, tiered compilation, ReadyToRun and Native AOT

Basic★ Must knowLesson 3 of 11
csharp
public static int Add(int a, int b) => a + b;

compiles to IL (stack-based, CPU-independent):

text
.method public hidebysig static int32 Add(int32 a, int32 b) cil managed
{
  ldarg.0      // push a
  ldarg.1      // push b
  add          // pop two, push sum
  ret          // return top of stack
}

and at runtime the JIT turns it into native code for the actual CPU:

text
; x64
lea eax, [rcx+rdx]
ret
TechniqueWhen code becomes nativeProsCons
JIT (default)At first call of each methodOptimises for the actual CPU and runtime profileStartup cost ("warm-up")
Tiered compilation (.NET Core 3+)Tier 0 quick JIT first, tier 1 optimised for hot methods (after ~30 calls), with Dynamic PGO (on by default since .NET 8)Fast startup and fast steady stateMore complex
ReadyToRun (R2R)Precompiled native code inside the DLL; JIT can still re-optimiseFaster startup, still flexibleLarger files
Native AOT (.NET 7+)Whole app compiled to a native executable at publishInstant start, small memory, no JIT, no runtime installNo dynamic code loading, reflection limits (trimming), longer builds
NGen (.NET Framework)Native images in a machine cacheFaster startupFragile, Framework-only
bash
dotnet publish -c Release -r linux-x64 -p:PublishReadyToRun=true
dotnet publish -c Release -r win-x64 -p:PublishAot=true