.NET Internals7h estimated

JIT Compilation in .NET

Difficulty
Importance

The problem

Intermediate language (IL) isn't machine code, so it can't run directly on the CPU — something has to translate it, and doing that translation efficiently, without a slow startup delay or wasted work retranslating the same method repeatedly, is a real engineering problem with more than one reasonable answer.

Why now

The CLR and managed execution already established that .NET code runs as IL, not machine code, leaving the translation step unexplained; the JavaScript engine and JIT already covered one JIT strategy (interpret, then optimize hot functions) for a very different, dynamically-typed language — .NET's JIT solves the same translation problem for a statically-typed, compiled-first one, which changes what's worth optimizing and when.

Mental model

.NET's JIT compiles each method to native machine code the first time it's actually called, then reuses that compiled code for every subsequent call — unlike a purely interpreted start, there's no repeated re-interpretation, just a one-time compilation cost paid lazily, per method, exactly when it's needed. Tiered compilation refines this further: a quick, less-optimized first compilation gets methods running fast, with a slower, more optimized recompilation kicking in later for methods called often enough to be worth the extra investment — the same 'watch what's hot, then optimize it' instinct the JS engine's JIT already established, applied to a different starting point.

Requires

Helps

Used in

Projects

  • Benchmark a method's execution time on its very first call versus its 1000th call in a tight loop, and explain the difference in terms of JIT compilation and tiered recompilation
  • Research and explain, in your own words, the tradeoff ahead-of-time (AOT) compilation makes against JIT — faster startup, but no runtime-adaptive optimization

Examples

  • A method's very first invocation pays a one-time JIT compilation cost; every subsequent call reuses the already-compiled native code, which is why microbenchmarks that ignore 'warm-up' are misleading
  • ASP.NET Core applications using ReadyToRun images ship some pre-JIT-compiled code specifically to reduce the cold-start latency of the first few requests after deployment

Resources

Mastery checklist