The 8th of November, 2022 was an important date for all .NET developers, as Microsoft released .NET 7. It is an STS (standard-term support) version with 18 months of support. One of the main changes that .NET 7 provides is a more developed unification of developing desktop and mobile software, as well as web, cloud, gaming, IoT, and AI solutions than it was in the 6th release.
Alongside, Microsoft has released Entity Framework Core 7, ASP.NET Core 7, .NET MAUI (Multi-platform App UI), C# 11, F# 7, Windows Presentation Foundation, Windows Forms, Windows Presentation Foundation, and the Orleans 7.
The increased performance is another great feature of this release which is shortly explained in this article. Also, opinions from several .NET experts are added so you can have a more diverse view. Furthermore, a performance check-up of nopCommerce after upgrading to .NET 7 is described and visualized.
Significantly increased productivity of .NET 7
As a result of Microsoft’s hard work, .NET 7 has achieved its goals that were mentioned when developing .NET 5. Even though it is an STS (standard term support), .NET 7 creates a lot of opportunities for further releases.
To help you understand more about .NET 7 and convince you to start using this version, the nopCommerce team would like to describe one of the main updates, which is performance. Basically, all .NET 7 improvements have been made to increase the framework's productivity. However, there are enhancements in .NET 7 that directly affect performance.
These are the main changes:
1. Native AOT
It creates an independent program with no external dependencies in the file format of the target platform. Without IL or JIT, Native AOT is totally inartificial and has a short launch time and a self-contained deployment. Native AOT concentrates on console apps and necessitates app trimming in .NET 7.
2. On-stack replacement
It serves as an addition to a tier-based compilation. On-stack replacement enables the runtime to alter the code being executed by a method that is currently in use while it is still "on stack." Midway through their execution, long-running procedures can transition to more efficient variants.
3. Profile-guided optimization
<TieredPGO>true</TieredPGO> to your project file profile-guided optimization (PGO) is now more simple to enable and compatible with OSR. Delegates are among the many things that PGO can measure and enhance.
The higher performance indicators in reflection use come from the significant cost savings of making calls of the same object element multiple times. According to Microsoft assumptions, performance increased by 4 times.
Last but not least is Language-Integrated Query (LINQ). By using language-integrated query comprehension syntax or directly using methods on the
System.Linq.Enumerable, it is a productivity tool that makes it possible to express otherwise sophisticated tasks in a basic way.
The following Enumerable methods received performance improvements: Max, Min, Average, and Sum. This was achieved through the use of processing vectorization using the Vector<T> data type. Now it is possible to use the updated methods in situations where code execution speed and allocated memory are critical.
Visit the “Performance improvements in the .NET 7” blog post for a detailed look at several of the features that are related to performance and make .NET 7 so quick.
Thoughts of .NET experts about moving to .NET 7
In addition to evaluating the performance of the nopCommerce platform, we have asked several experienced .NET developers. It may help you understand if migrating to .NET 7 is worthwhile for your projects. Here are some quotes from .NET experts:
“.NET 7 focuses on performance improvements, including an enhanced JIT compiler, hardware intrinsics, and a redesigned garbage collector. It also features improved HTTP/2 support, built-in OpenTelemetry for request tracing, and the ability to accelerate builds in Visual Studio. Removing Docker dependencies reduces build times, and supports ARM64, making it easier for developers to build high-performance apps that can run on different devices and platforms.”
ー Vithal Wadje, IoT and Azure Cloud Platform expert, blogger and Senior Software Engineer at bp
“With its latest release, .NET 7 delivers faster startup times, runtime performance, networking speed, optimized WebAssembly performance, and a lot of new APIs, that help me to create incredibly fast web applications. Actually, it's really fun to work with the new .NET.”
ー Jürgen Gutsch, .NET blogger and Software Engineer at YOO AG
“In general, I found the performance the most helpful update of .NET 7. It's basically free and performance is never a bad thing. Also, I personally like two new methods in .NET 7, Stream.ReadExactly and Stream.ReadAtLeast. The most visible enhancement seems to be SaveChanges improvements in EF Core 7 if you're using EF Core.”
ー Jiří Činčura, .NET, C# and Firebird expert, blogger, and a software engineer at Microsoft
Performance improvements in the 4.60 nopCommerce release
As a testing tool, we decided to choose a fairly popular SaaS service for load and scalability testing - loader.io. The server on which the application is deployed is an average machine used for development:
- CPU - Intel(R) Core(TM) i5-7400 CPU 3.00 GHz;
- RAM - 16,0 ГБ.
The tests were run under Windows 10 Pro (21H2 version, 19044.2604 build) and IIS 10 (10.0.19041.2604). For the test, we took the standard database that comes with the installation of the application. All this is running under MS SQL Server 2019 (19.0.2000).
To simulate the load, connecting 250 users within a minute was chosen as a test configuration. Users will visit several random pages of the application. This will be enough to trace the overall picture of the application's behavior and will allow you to clearly see the difference relative to previous versions.
Next, we will give a table of correspondence between versions of the nopCommerce application and versions of the .NET platform.
|.NET||.NET 7||.NET 6||.NET 5|
We ran 3 identical load tests in a row to get an idea not only about the nature of the load but also about the memory consumption on the server. The average results after several runs are presented below.
Before presenting response time results, it is important to say that the lower measurement, the better. You can clearly see the performance increase relative to .NET 5 and .NET 6 versions - by 53.3% and 13.6% respectively. These are the best indicators that we managed to get in the process of measuring performance.
Although the difference between the last two versions is small, we still see that Microsoft still pays due attention to work on performance. Each new version of the framework becomes faster than the previous one, this is a very nice bonus that you get just by rebuilding your project for .NET 7 and nothing else.
We would like to present and discuss the measurement of application memory consumption. In this case, the less memory involved, the better. The tests were run sequentially for each platform without resetting the application pool. We are accustomed to the fact that the cost of increased performance is the inevitable overhead of memory resources. Optimization in .NET 6 gave some hope that the platform's appetite was being controlled, but in general, we understood that if performance increased, then memory consumption would increase.
But this time the picture has changed exactly the opposite. Resources allocated to memory have been reduced compared to the previous version. You can see the results in the diagram below.
Another interesting thing that requires a closer look at is how the load was distributed in an application on the .NET 7 platform, and comparing similar data for tests based on .NET 6. Here we are again for a surprise.
Load distribution in .NET 7
Load distribution in .NET 6
The test conditions are such that 250 users should connect to the server within 1 minute. The graph shows that due to the fact that the response of the system on the .NET 7 platform is faster (blue line), the processing of test users per unit of time is more linear (green line).
We no longer see bursts, as was the case with .NET 6. This indirectly indicates that the server on .NET 7 is somewhat easier to handle the load and the system is confidently in a state of equilibrium. While the system on .NET 6 had to increase the influx of users in view of the fact that the response time is not only longer, but also more inconsistent.
The new .NET 7 platform is definitely faster than its predecessor. An important fact is that to ensure its work, it is not necessary to allocate more resources than was previously required. In general, if we evaluate the feasibility of updating the platform, then we believe that it is worth it. You get not only increased productivity but many other useful innovations that can be used in the development of projects of any level.
Usually, short-term support updates of a product or framework are used as a mediator between two main releases. However, it is not a certain case for .NET 7, as it has new features and various updates. The nopCommerce team has decided to evaluate performance improvements since there is a direct impact on our eCommerce platform.
Based on the productivity enhancements after migrating to .NET 7, as well as the expertise of experienced developers, it can be fairly concluded that this STS version is worth being updated on. Apart from that, you may find other helpful features that can improve development efficiency and provide a lot of opportunities to scale your projects.
We have also described the results of other .NET and .NET Core updates in our previous articles: “Platform's productivity improvements: Migration from .NET 5 to .NET 6”, “Migration from .NET Core 2.2 to .NET Core 3.1: nopCommerce experience” and “A Step-by-Step Guide to Migrating a Project from ASP.NET MVC to ASP.NET Core”.