Back to results for “CLR & Runtime”
.NET › CLR & Runtime

How does the CLR's Dynamic Profile-Guided Optimization (Dynamic PGO) improve JIT-compiled code quality at runtime?

Advanced

Answer

Dynamic PGO (enabled by default since .NET 8) instruments Tier 0 code with lightweight counters tracking actual runtime behavior (which branches are taken, which types appear at a call site), then uses this real, observed profile data when generating the final optimized Tier 1 code -- producing better-optimized native code tailored to the application's actual runtime behavior than static, compile-time-only optimization heuristics could achieve, since real execution patterns often differ from what static analysis alone can predict.
<PropertyGroup>
  <TieredPGO>true</TieredPGO>  <!-- default: true in .NET 8+ -->
</PropertyGroup>

// The JIT observes, e.g., that a virtual call site almost always resolves
// to the same concrete type, and generates optimized code assuming that case
Real-world example A benchmark comparing .NET 6 (without Dynamic PGO) to .NET 8 (with it enabled by default) on the same polymorphism-heavy business logic shows measurable throughput improvement purely from the JIT's better runtime-informed optimization decisions.

Common follow-ups: What's the overhead of the instrumentation phase before Tier 1 recompilation?;How does this interact with Native AOT, which has no runtime profiling phase?