Roadmap › .NET Internals — CLR, CTS, CLS, IL, JIT, Memory Management & Garbage Collection › Module: Platform and Compilation
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| Technique | When code becomes native | Pros | Cons |
|---|---|---|---|
| JIT (default) | At first call of each method | Optimises for the actual CPU and runtime profile | Startup 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 state | More complex |
| ReadyToRun (R2R) | Precompiled native code inside the DLL; JIT can still re-optimise | Faster startup, still flexible | Larger files |
| Native AOT (.NET 7+) | Whole app compiled to a native executable at publish | Instant start, small memory, no JIT, no runtime install | No dynamic code loading, reflection limits (trimming), longer builds |
| NGen (.NET Framework) | Native images in a machine cache | Faster startup | Fragile, Framework-only |
bash
dotnet publish -c Release -r linux-x64 -p:PublishReadyToRun=true
dotnet publish -c Release -r win-x64 -p:PublishAot=true