Sasha Goldshtein – Making .NET Applications Faster
In this three-day workshop, you will learn how to measure, understand, improve, and test the performance of your .NET applications and systems. Tuning .NET application performance requires in-depth familiarity with the CLR, the garbage collector, the just-in-time compiler, and various .NET Framework services. Good performance measurement tools that can be deployed into production environments are also a must. This workshop teaches you how to combine a solid understanding of your platform with tools that point out where to focus and what to improve. At least 30% of the time is invested in detailed hands-on labs, which are available to you at any time during and after the course. The labs also provide instructions for applying the lessons learned to your own systems after the course.
During most of the first day, we will focus on performance measurement tools that are relevant for both development and production environments. Rather than covering a breadth of commercial profiler offerings, we will explore the free ETW platform built into Windows and the CLR, which can be used to profile applications for CPU and wall-clock time bottlenecks, to obtain information on memory allocations and garbage collections on the method level, to understand disk accesses and network requests performed by your application, and many other important metrics. Along with the ETW tools we will begin discussing .NET garbage collection internals: mark-sweep-compact phases, generations, server and workstation GC, Large Object Heap tuning, and the interaction between GC and the Windows virtual memory manager. We will use tools like PerfView and VMMap to identify and improve inefficient GC behavior.
During the second day, we will wrap up our discussion of .NET memory management by reviewing best practices for interacting with the garbage collector, and thoroughly understanding finalization internals and the potential performance issues involved with excessive use of finalization. We will also see how to analyze .NET application memory dumps to identify memory leaks over time, and how to generate dumps automatically for continuous monitoring. Next, we will turn to reviewing CPU bottlenecks in .NET applications — first, by learning how to monitor and eliminate simple CPU bottlenecks, and then by experimenting with tools that show thread relationships and subtle behaviors such as lock contention and convoys. We will also discuss CPU caches and pipeline stalls, which can again be monitored to identify and improve problematic behavior.
During the third and final day, we will discuss additional advanced techniques for improving the performance of CPU-bound algorithms. We will focus on vectorization (SIMD instructions), which has recently become available for .NET developers to use with the rewrite of the CLR JIT compiler (RyuJIT). Later in the day, we will discuss a variety of shorter topics, including tips for improving application startup times, navigating your way through the vast number of .NET collection classes, and using unsafe code (C# pointers) when the performance requirements dictate it.