Microsoft details .NET 11's hundreds of performance gains

Microsoft details .NET 11's hundreds of performance gains

Microsoft's .NET team published its annual performance write-up for .NET 11 on the devblogs.microsoft.com blog, continuing a series that has run every year back to .NET Core 2.0 (through 2.1, 3.0, and .NET 5 through 10). The post frames the release with a This Is Spinal Tap joke: where Nigel's amplifier dials supposedly go to eleven instead of ten, .NET 11 is presented as genuinely "one louder" than .NET 10, meaning another year of real, measured runtime and library optimizations rather than a cosmetic bump. The author says the post walks through hundreds of individual improvements: a bounds check removed here, an allocation eliminated there, a lock no longer taken, a loop shortened, a comparison folded to a constant, a redundant check hoisted out of a loop, instructions fused, a syscall avoided, an array copy handed off to SIMD, and so on, each one small but compounding with the rest. To let readers reproduce the numbers themselves, the post gives a full BenchmarkDotNet setup: a console project multi-targeting net11.0 and net10.0, pinned in the example to .NET 11 package version 11.0.0-rc.1.26425.128 (still a release candidate at the time of writing) against .NET 10.0.12, run with BenchmarkDotNet 0.16.0-preview.1. From there the retrieved text moves into its first technical section, the JIT compiler, and specifically "deabstraction": the runtime's ability to strip away the cost of abstractions such as C# interfaces once it can prove the extra flexibility isn't actually being used. It walks through a worked example: a virtual Speak() call on an Animal reference that is really always a Dog. Without extra information, the JIT has to compile this as an indirect call through the object's vtable, shown in the post as three dependent x64 memory loads followed by an indirect call, which the CPU cannot safely predict and which blocks the JIT from inlining the callee. Inlining matters because it lets the caller's other optimizations, such as constant propagation and further devirtualization, reach into the callee's code too, so a chain of small virtual calls can collapse into a handful of instructions once the JIT can see through them. The post lists several ways .NET already resolves the target statically, such as when a variable is freshly allocated as a concrete type, when its declared type is a sealed class, or, under NativeAOT with whole-program analysis, when only one concrete subclass of an abstract type exists anywhere in the compiled application. For the remaining cases it cannot resolve statically, the post turns to profile-guided optimization (PGO): under tiered compilation a method first runs as an unoptimized "Tier 0" build instrumented with lightweight probes that record which branches are taken and which concrete types actually show up at a given call site, and once the method is called or looped enough, the runtime recompiles it as an optimized "Tier 1" build that can bake in what was actually observed at runtime. The retrieved text breaks off partway through the PGO discussion, before reaching the post's later sections or any of the concrete before/after numbers for the hundreds of improvements it promises to cover.

Key facts

  • Microsoft published its annual .NET performance blog post, this time for .NET 11, continuing an unbroken series back to .NET Core 2.0
  • The post says it covers hundreds of individual runtime and library performance improvements, framed with a This Is Spinal Tap "one louder" joke
  • Its benchmarking setup multi-targets net11.0 and net10.0, comparing .NET 11 package 11.0.0-rc.1.26425.128 (a release candidate) against .NET 10.0.12 using BenchmarkDotNet 0.16.0-preview.1
  • The first technical section covers JIT "deabstraction": eliminating the cost of virtual calls through devirtualization, illustrated with a Dog/Cat/Animal example and its x64 assembly
  • It also explains profile-guided optimization: tiered compilation runs an instrumented Tier 0 build first, then recompiles hot methods as an optimized Tier 1 build based on what was actually observed at runtime

Why it matters

This is Microsoft's flagship annual account of where .NET's speed comes from: not one headline feature but hundreds of small wins in the runtime and libraries that compound over a release cycle. Because many of them live in the JIT compiler itself, they can benefit existing application and library code automatically, without the code being touched or recompiled by hand.

Who it affects

C#, F#, and Visual Basic developers running on .NET, particularly anyone with CPU-bound or high-throughput managed code, since JIT-level changes such as better devirtualization and profile-guided optimization apply broadly across an application rather than to one API.

How to use it

The post is written to be reproduced: it gives the exact project file and commands to multi-target net10.0 and net11.0 with BenchmarkDotNet, so a reader can install both .NET 10 and .NET 11, drop each benchmark's code into Program.cs, and run the side-by-side comparison themselves. At the time of writing, .NET 11 was still at a release-candidate build (11.0.0-rc.1.26425.128), not yet generally available.

How solid is it

The claims rest on Microsoft's own reproducible BenchmarkDotNet micro-benchmarks rather than marketing figures, and the post explicitly walks through the mechanics (assembly output, tiered compilation behavior) rather than only stating results. The retrieved text cuts off before the post reaches the concrete before/after numbers for most of the "hundreds" of improvements it promises, so this retelling covers the framing and the first technical section rather than the full tally.

Risks and caveats

The author's own disclaimer applies: these are micro-benchmarks measuring operations short enough that results vary with hardware, OS, runtime configuration, and what else the machine is doing at the time. The post itself does not name specific individual authors in the portion retrieved, and no publication date for .NET 11 or the post is given there either.

“In contrast, .NET 11 is actually one higher, one louder.”

— Microsoft .NET blog, "Performance Improvements in .NET 11"