.NET 5 already has a wealth of performance enhancements and still, there are likely chances to include a lot more improvement before the official release scheduled later this year which contributed to the creating .NET 5 with the myriad of performance improvements. The following areas of the .NET platform will see an improvement in performance once .NET 5 releases.
Table of Content
- 1. Setup
- 2. Garbage Collection
- 3. Just-In-Time (JIT) Compiler
- 4. Intrinsics
- 5. Runtime Helpers
- 6. Text Processing
- 7. Regular Expressions
- 8. Threading and Async
- 9. Collections
- 10. LINQ
- 11. Networking
- 12. JSON
- 13. Trimming
- 14. New Performance-Focused APIs
- 15. New Performance-Focused Analyzers
- 16. Peanut Butter
Benchmark.NET is now a simple tool for measuring the performance of .NET code, making it easy to analyze the throughput and allocation of code snippets. The large number of our examples in this post are evaluated using microbenchmarks note down using that tool. To make it easy to follow at home (literally for many of us these days), we started using the Dot Net tool to create a directory and scaffold it:
mkdir Benchmarks cd Benchmarks dotnet new console
And the benchmarks we have generated have been enhanced to look at the contents of the csproj as follows:
Exe true true net5.0;netcoreapp3.1;net48
Read More: What’s New In .net Productivity?
For anyone interested in .NET and performance, garbage collection is always on the mind. Many efforts go into reducing the allocation, not because the act of allocating work itself is particularly expensive, but because of the follow-on costs by the garbage collector (GC) cleaning up after that allocation. It doesn’t matter how much work goes into reducing the allocation, however, the vast majority workloads will incur them, and so it’s important to continually push the boundaries of what GC is able to accomplish, and how quickly.
Just-In-Time (JIT) Compiler
.NET 5 is exciting version of the Just-in-Time (JIT) compiler, with many improvements of all the way to finding a way to access the release. Like any compiler, improvements made to JIT can have wide-reaching effects. Often individual changes have little effect on the individual piece of the code, but such changes are then magnified by the sheer number of places they apply.
JIT has almost unlimited optimizations that can be added, and given unlimited amount of time to run such optimizations, JIT can create the most optimal code for any given scenario. But JIT does not have an unbounded amount of time. The “just-in-time” nature of JIT means it is performing the compilation as the application run: when no method has yet been complied is invoked, JIT is required to provide an assembly code for it on-demand. That means the thread will not be able to move forward until compilation has completed, which means that JIT needs to be strategic in what optimization it applies and how it selects to utilize its limited time budget.
In .NET Core 3.0, over a thousand new hardware intrinsic methods were added and recognized by JIT to enable C # codes to directly target instruction sets such as SSE4 and AVX2 (see docs). This were then used to great advantage in the set of APIs in core libraries. However, the intrinsic were limited to x86 / x64 architectures only.
GC and JIT represent large portion of the runtime, but a significant portion of the functionality still remains in the runtime outside of these components, and similar improvements have been seen.
Text-based processing is the bread-and-butter of many applications, and many efforts in each release goes into improving the fundamental building blocks on top which everything else is built. The changes extend from the micro optimizations in helpers processing individual characters all the up to overhauls of entire text-processing libraries.
A very specific but extremely common form of parsing is through regular expressions. The System.Text.RegularExpressions namespace has been in .NET for many years, all the way to NET Framework 1.1. Use it yourself. Within the .NET implementation, and directly through thousands upon thousands of applications.
Threading and Async
One of the biggest changes around asynchronous in .NET 5 is actually not enabled by default, but is another experiment to get feedback. The async/await feature in C # has revolutionized how developers target .NET writes asynchronous code. Sprinkle some async and await around, the change some return types to be tasks.
Over the years, C# has gained a plethora of valuable features. Many of these features are concentrated on developers being capable to more bluntly write code, the language/compiler is accountable for all boilerplate. However, some features focus less on productivity and more on performance, and such features are a great boon to the core libraries, which can be used to make everyone's program's more efficient.
An earlier release of .NET Core saw a large amount of churn the System.linq codebase, in particular to improve performance. That flow has slowed, but .NET 5 still sees performance improvements in LINQ.
These days networking is a crucial component of almost any application, and the great networking performance of paramount important. As such, every release of .NET now sees many attentions paid to improving networking performance, and .NET 5 is no exception.
Significant improvements were made to the System.text.json library for .NET 5 and specifically for the JsonSerializer, but many of these improvements actually ported back to .NET Core 3.1 and were published as part of servicing fixes. However, there are some nice improvements that show up in .NET 5 beyond those.
.NET core until 3.0 was primarily focused on server workloads, with the pre-eminent application model on the ASP.net core platform. With .NET Core 3.2, Blazor support for browser applications has been released, but based on mono and library mono stacks. With .NET 5, Blazor utilizes .NET 5 mono runtime and all the similar .NET 5 libraries shared by each other application model. This brings a prior twist to performance as well as size. While code size has always been an important issue (and is important for Native applications), the scale required for successful browser-based deployment really brings it to the forefront, as we need to be concerned about download size. Not focused with the net core in the past
New Performance-Focused APIs
This post has highlighted a plethora of an existing API that simply get better when running on Net5. In addition, .Net 5 has many new APIs, some of which focused on helping developers write code faster.
New Performance-Focused Analyzers
The C# "Roslyn" compiler has a very important extension point called "Analyzers" or "Roslyn Analyzers". Analysts plug into the compiler and are given full read access to all the sources the compiler is operation over as well as the compiler's parsing and modeling of that code,which enabling developers to plug in their own custom analysis to a compilation.On top of that, analysts run not only as part of builds, but also in IDE as developers writing their code, which enabling analysts to present suggestions, warnings, and errors on how developers can improve their code. Analyzer developers can also author "fixers" that can be invoked to the IDE and automatically replace the flagged code with "fixed" alternatives and all of these components can be distributed through NuGet packages, making it easier for developers to consume arbitrary analysis written by others.
.NET 5 release will be an advanced open source platform for building your applications that works cross-platform with multiple operating systems. We hope this article will help you to understand the Performance Improvements in .NET 5.