Announcing .NET 5.0 Preview 2
Today, we’re releasing .NET 5.0 Preview 2. It contains a set of smaller features and performance improvements. We’re continuing to work on the bigger features that will define the 5.0 release, some of which are starting to show up as initial designs at dotnet/designs. The .NET 5.0 Preview 1 post covers what we are planning on building for .NET 5.0. Please take a look at the post and the designs repository and share any feedback you have. And, of course, please install Preview 2, and test any workloads you can with it.
You can download .NET 5.0 Preview 2, for Windows, macOS, and Linux:
Let’s look at some of the improvements in Preview 2.
Code quality improvements in RyuJIT
Every release includes a set of changes that improve the machine code that the JIT generates (we call this “code quality”). Better code quality means better performance. In summary, about half of the following improvements are actual new optimizations and the other half are due to changing the flow of RyuJIT to enable existing optimizations to apply to more code patterns.
- Use xmm for stack prolog – dotnet/runtime #32538 — Change to x86/x64 prolog zeroing code. Improvements: Json; TechEmpower. Credit: Ben Adams.
- Add ValueNumbering support for GT_SIMD and GT_HWINTRINSIC tree nodes – dotnet/runtime #31834 — Enable the optimizer for SIMD and hardware intrinsic types.
- Use GT_NULLCHECK for unconsumed indirections – dotnet/runtime #32641 — Remove redundant null checks.
- invoke nullable box optimizations earlier – dotnet/runtime #32269 — Improve optimizations for
- Optimize range checks for various array index patterns – dotnet/runtime #1644 — Improvement in range check elimination.
obj.GetType() != typeof(X)for sealed classes – dotnet/runtime #32790 — Improvement to type check expression.
- Eliminate duplicate zero initializations more aggressively – dotnet/runtime #31960 — Better and broader approach for eliminating duplicate zero initializations.
- Fix method and basic block flags used by early opts – dotnet/runtime #2196 – Enables certain optimization to be used more often. For example, replacing array length with a constant now occurs much more often.
If you like this style of improvement or are an ARM64 user, you may be interested in Vectorise BitArray for ARM64, coming soon (already merged, but not in Preview 2). This change demonstrates a lot of focus on ARM64 in .NET 5.0.
- Card mark stealing – dotnet/coreclr #25986 — Server GC (on different threads) can now work-steal while marking gen0/1 objects held live by older generation objects. This means that ephemeral GC pauses are shorter for scenarios where some GC threads took much longer to mark than others.
- Introducing Pinned Object Heap – dotnet/runtime #32283 — Implemented part of the POH (Pinned Object Heap) feature – the part internal to GC. This new heap (essentially a peer to LOH) will allow the GC to manage pinned objects separately, and as a result avoid the negative effects of pinned objects on the generational heaps.
- Allow allocating large object from free list while background sweeping SOH – dotnet/runtime #2103 — Enabled LOH allocations using the free list while BGC is sweeping SOH. Previously this was only using end of segment space on LOH. This allowed for better heap usage.
- Background GC suspension fixes – dotnet/coreclr #27729 — Suspension fixes to reduce time for both BGC and user threads to be suspended. This reduces the total time it takes to suspend managed threads before a GC can happen. dotnet/coreclr #27578 also contributes to the same outcome.
- Fix named cgroup handling in docker – dotnet/runtime #980 — Added support to read limits from named cgroups. Previously we only read from the global one.
Please take a moment to try out Preview 2, possibly in a container, a VM. We’d like your feedback on the quality of the release. There is a lot more coming, over the next several months, leading up a November release.
We’re running 50% of the .NET Website traffic on .NET 5.0 as a test case, using Azure load balancing. We’ve been doing that since days after we released Preview 1. You may remember us doing something similar with .NET Core 3.0 and 3.1. By splitting the traffic 50/50, we can ensure that 5.0 gets consistently better with constant performance data available to us. This model keeps us honest, and it’s also a great testing approach. We trust our most important site with ALL of our previews, in production (which we don’t recommend for anyone else). That should make adopting our final release a pretty easy choice for you. The version number is in the footer of .NET website; feel free to check at any time.
Stepping back for a minute, many of you might be interested in how the the folks on the .NET Team at Microsoft are doing. We’re doing well. We have lots of Teams meeting every day to organize and support one another, and are just as active on GitHub as ever. The team is close-knit, and collaborating across multiple time-zones. We’re all focused on this release, and very much intending to deliver what we set out to deliver when we first defined our plans, after releasing .NET Core 3.0. Take care.