Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
High-Performance Programming in C# and .NET

You're reading from   High-Performance Programming in C# and .NET Understand the nuts and bolts of developing robust, faster, and resilient applications in C# 10.0 and .NET 6

Arrow left icon
Product type Paperback
Published in Jul 2022
Publisher Packt
ISBN-13 9781800564718
Length 660 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Jason Alls Jason Alls
Author Profile Icon Jason Alls
Jason Alls
Arrow right icon
View More author details
Toc

Table of Contents (22) Chapters Close

Preface 1. Part 1: High-Performance Code Foundation
2. Chapter 1: Introducing C# 10.0 and .NET 6 FREE CHAPTER 3. Chapter 2: Implementing C# Interoperability 4. Chapter 3: Predefined Data Types and Memory Allocations 5. Chapter 4: Memory Management 6. Chapter 5: Application Profiling and Tracing 7. Part 2: Writing High-Performance Code
8. Chapter 6: The .NET Collections 9. Chapter 7: LINQ Performance 10. Chapter 8: File and Stream I/O 11. Chapter 9: Enhancing the Performance of Networked Applications 12. Chapter 10: Setting Up Our Database Project 13. Chapter 11: Benchmarking Relational Data Access Frameworks 14. Chapter 12: Responsive User Interfaces 15. Chapter 13: Distributed Systems 16. Part 3: Threading and Concurrency
17. Chapter 14: Multi-Threaded Programming 18. Chapter 15: Parallel Programming 19. Chapter 16: Asynchronous Programming 20. Assessments 21. Other Books You May Enjoy

Overview of Microsoft .NET 6

Microsoft .NET 6 is the latest incarnation of .NET. You can access the downloads at https://dotnet.microsoft.com/download/dotnet/6.0. The downloads are available for Windows, macOS, and Linux users.

Note

To get the most out of .NET 6 and C# 10.0, it is best that you have Visual Studio 2022 or later installed.

The .NET 6 API documentation is available at https://docs.microsoft.com/dotnet/api/?view=net-6.0.

Microsoft .NET 5 and later will no longer carry the Core or Framework suffix, as per the following article: https://redmondmag.com/articles/2019/12/31/coming-in-2020-net-5.aspx. Microsoft's goal with version 5 and later of the .NET platform is to create a single platform for the .NET development of WinForms, WPF, Xamarin.Forms, ASP.NET Core, and all other forms of .NET development. Xamarin.Forms becomes Microsoft MAUI, with the main difference between versions being that the new Microsoft MAUI will only use a single project to target all operating systems and devices.

Moving to one unified platform

The infrastructure for .NET 6 consists of runtime components, compilers, and languages. Microsoft .NET SDK will sit on top of this infrastructure. The tools that will be available include the command-line interface, Visual Studio Code, Visual Studio for Mac, and, of course, Visual Studio.

With the unified platform, you can write desktop applications using WinForms, WPF, and UWP. Web applications can be written using ASP.NET. Cloud applications will target Microsoft Azure. Mobile applications will be written using Microsoft MAUI. Games, virtual reality (VR), and augmented reality (AR) applications will be developed in Unity, using Visual Studio 2022 or higher as the C# code editor. IoT will target ARM32 and ARM64 architectures. Finally, you will be able to develop artificial intelligence (AI) applications using ML.NET and .NET for Apache Spark.

Microsoft is planning on producing a single .NET runtime and framework that is uniform in its developer experience and runtime behavior across applications and devices. This will be accomplished by building a single code base that combines the best elements of.NET Framework, .NET Core, Mono, and Xamarin.Forms.

The main features of.NET 6 are as follows:

  • Unified developer experiences, regardless of the applications being developed and the devices being targeted.
  • Unified runtime experiences across all devices and platforms.
  • Java interoperability will be available on all platforms. This is stated in the Redmond Magazine article called Coming in 2020: .NET 5, The Next Phase of Microsoft's .NET Framework: https://redmondmag.com/articles/2019/12/31/coming-in-2020-net-5.aspx.
  • Multiple operating systems will be supported for Objective-C and Swift.
  • AOT will be supported by CoreFX to provide static .NET compilation, support multiple operating systems, and produce assemblies that are smaller in size.

Now, let's look at some of the new features of .NET 6 from a high-level viewpoint.

Garbage collection

The garbage collector's performance regarding marking and stealing has been improved. When a thread has finished its marking allotment, it can steal outstanding marking work from other threads. This speeds up the process of collecting items to be garbage collected. Reduced lock contentions on computers with higher core counts, improved de-committing, avoidance of costly memory resets, and vectorized sorting are just some of the new garbage collection performance improvements in .NET 6.

Just-In-Time compiler

In .NET 6, the Just-In-Time (JIT) compiler has also been improved. You can apply various optimizations to the JIT, and it has an unlimited amount of time to implement those optimizations. Ahead-Of-Time (AOT) is just one of the various techniques provided to the JIT so that it can compile as much code as it can before executing the application. The JIT now sees the length of an array as unsigned, which improves the performance of mathematical operations carried out on an array's length. There are still many changes being made.

Suffice to say that between the JIT and the GC, the performance improvements that have been made to JIT and GC concerning memory and compilation optimizations are just two reasons alone to migrate to .NET 6.

The JIT also recognizes more than a thousand new hardware intrinsic methods. These methods allow you to target various hardware instruction sets from C#. You are no longer tied to just x86_x64 hardware instruction sets.

Several runtime helper functions are available in the JIT. These helper functions enable the JIT compiler to manipulate the source code so that the code runs must faster. Generic lookups are much faster now, as they no longer need to employ slower lookup tables.

Text-based processing

Performance enhancements have also been made within the text-based processing elements of .NET 6. These include (but are not limited to) processing whitespace in the System.Char class, which requires less branching and fewer arguments. Because this class is used in various text-processing objects and methods within .NET 6, the speed of processing text in .NET 6 will be generally improved. DateTime processing is also at least 30% faster due to optimizations in extracting the date and time components from the raw tick count. Performance improvements have also been made to string operations due to culture-aware modifications of StartsWith and EndsWith. By utilizing stack allocation and JIT devirtualization, the performance of data encoding, such as UTF8 and Latin1 encoding, has also been enhanced.

Regular expression (RegEx) performance has also been improved in .NET 6. The RegEx engine has had performance improvements that increase textual processing by up to three to six times and even more. The CharInClass method is more intelligent in determining if characters appear within the specified character class. Character and digit comparisons use lookup tables and various method calls are inlined, providing improved RegEx processing. Generated code for various expressions has been improved. Searching for RegExes is carried out using span-based searching with vectorized methods. The need for backtracking has been eliminated as it analyzes RegExes during the node tree optimization phase and adds atomic groups that do not change the semantics but do prevent backtracking. These are only some of the improvements to RegEx performance. But there are many more.

Note

For more in-depth knowledge on .NET 5 performance improvements to RegExes, please read the following very detailed post by Stephen Toub: https://devblogs.microsoft.com/dotnet/regex-performance-improvements-in-net-5/.

Threading and asynchronous operations

Threading and asynchronous operations have also received a performance boost in .NET 5 with the experimental addition of async ValueTask pooling. You can turn on pooling by setting DOTNET_SYSTEM_THREADING_POOLASYNCVALUETASK to true or 1. Pooling creates state machine box objects that implement the interfaces, IvalueTaskSource, and IValueTaskSource<TResult>. The runtime adds these objects to the pool. Volatility has also received performance improvements in ConcurrentDictionary, with performance improving as much as 30% on some ARM architectures.

Collections and LINQ

The collections have also seen several performance enhancements, mainly to Dictionary<TKey, TValue>, HashSet<T>, ConcurrentDictionary<TKey, TValue>, and System.Collections.Immutable. The HashSet<T> collection's implementation has been rewritten and re-synchronized with Dictionary<TKey, the TValue> implementation, and moved further down the stack. The performance of foreach when iterating through an ImmutableArray<T> has been improved, and the generated code has been reduced in size by the addition of the [MethodImpl(MethodImplOptions.AggressiveInlining)] annotation to the GetEnumerator method of ImmutableArray<T>. Other elements of the .NET collections, such as BitArray, have also seen performance improvements.

In .NET 5, LINQ has also seen further performance improvements, including OrderBy, Comparison<T>, Enumerable.SkipLast, and by making implementing Enumerable.Any more consistent with Enumerable.Count. These are only a few performance improvements that have been to the collections.

Networking and Blazor

Networking has received a lot of work on performance improvement, especially the System.Uri class (especially in its construction). The System.Net.Sockets and System.Net.Http namespaces have also seen performance improvements. Many improvements have been made to how JSON is processed with JsonSerializer in the System.Text.Json library for .NET.

As Blazor uses the .NET mono runtime and .NET 5 libraries, a linker has been added that trims code from the assembly that is not used down to the member level. The code to be trimmed is identified by static code analysis. User interface response times are also improved in Blazor Web Assembly applications, as the client-side code is downloaded before being executed, and behaves just like a desktop application – but from within the browser.

Furthermore, general improvements that have gone into .NET 5 include faster assembly loading, faster mathematical operations, faster encryption and decryption, faster interoperability, faster reflection emitting, faster I/O, and various allocations in various libraries.

New performance-based APIs and analyzers

A few new performance-focused APIs have been added to .NET 5. Internally, some of these APIs are already being used to reduce code size and improve the performance of .NET 5 itself. They focus on helping the programmer to concentrate on writing performant code and removing the complexity of tasks that have been previously hard to accomplish. These new APIs and improvements to existing APIs include Decimal, GC, MemoryExtensions, StringSplitOptions, BinaryPrimitives, MailAddress, MemoryMarshall, SslStream, HttpClient, and more.

The .NET 5 SDK has also seen the addition of some new performance-based analyzers. These analyzers can detect accidental allocations as a part of range indexing and offer ways to eliminate the allocation. Analyzers will detect the old overloads for the Stream.Read/WriteAsync methods and will offer fixes to enable automatic switching to the newer overload methods that prefer Memory overloads. In StringBuilder, it is more performant to use typed overloads to append non-string values such as int and long values. When situations are encountered by the analyzer where the programmer has called ToString() on a type that's being appended for which a typed overload exists, the fixer will detect these situations and automatically switch to using the correct typed overload. With LINQ, it is now more efficient to check if (collection.Count != 0) using the (!collection.IsEmpty) syntax. The old way will be detected by the analyzer and fixed to use the more performant new way. Finally, when you have worked to make your code faster, your code is made correct, as the analyzer flags cases that use loops to allocate memory from the stack using stackalloc. This helps prevent stack overflow exceptions from being raised.

To see the road ahead in terms of .NET's new development, you can view the .NET Core roadmap located at https://github.com/dotnet/core/blob/master/roadmap.md.

Now, let's look at C# 10.0.

You have been reading a chapter from
High-Performance Programming in C# and .NET
Published in: Jul 2022
Publisher: Packt
ISBN-13: 9781800564718
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime