Tag Archives: dotnet

Book review : Writing High-Performance .NET Code

Cover-Tall-2000x2828-212x300
Ben Watson has been a software engineer at Microsoft since 2008. On the Bing platform team, he has built one of the world’s leading .NET-based, high-performance server applications, handling high-volume, low-latency requests across thousands of machines for millions of customers.

More recently Ben Watson posted two articles on codeproject, both are “Best C# article of the month”. So you can trust this guy.

There are so many books, so many articles & blogs, so many tweets talking about .net performance. Why do we need another book in 2014 and even why do we still need to understand .net internals today when our applications may be hosted on servers with 16 cores and 112 GB of RAM (Azure A9) ?

First, optimizing your code will scale much more better than scaling up/adding new hardware. For sure, you can add more cores, more RAM to your production servers for few €/$ per month, and this is may be a pertinent approach in some cases.  But don’t be naive, a bottleneck in your application is like the sword of Damocles “with great fortune and power come also great peril and anxiety”

More than ever, it’s difficult to predict the performance of a single line of code. By integrating nuget packages, OSS librairies, commercial components … everywhere (“don’t reinvent the wheel, use a framework, they all say”) … our code becomes some kind of magic. In an Agile world, our codebase changes very often and it’s the same of our dependencies: Any commit could potentially destroy your application performance. Good developers have full tests suites (unit, integration, e2e, …) Why not performance tests and benchmarks ?

More than 13 years after the first version of .net, it’s still there, very competitive & efficient in many areas. We can use .net to develop web sites, universal apps, android/iOs app, …. “One language to rule them all, and it’s C#”. Recent additions like async/await and the new features of C# 6 show us that it’s an active and dynamic language. Learning .net runtime internals is certainly not useless.

This is my feeling about dotnet performance today. That’s why I bought this book one month ago.

If you’re a bit concerned about performance, you may know that it’s a very broad topic. What is performance? response time, CPU on a front server, low available memory on a back service … The famous quote of Donald Knuth “Premature optimization is the root of all evil” is a really good argument for detractors “don’t spend time of code optimizations, it’s useless”

One simple rule, maybe the most important in this book is : Measure, Measure, Measure! Don’t try to guess, it’s impossible; don’t try to optimize everything, it’s also impossible. By measuring accurately, you will be efficient. Most of the time to reach your performance goal, you just have to change a few areas in your code, and not everything.

In this book, the author lists a wide range of tools that could help you when investigating performance issues: Visual Studio Profiler, PerfView, CLR Memory Profiler, MeasureIt, … This tool chain should be part of every Performance Chief Architect. “Optimizing performance is meaningless if you do not have effective tools for measuring it”.

This book is quite recent (summer 2014), so the content is quite up-to-date; For example, there are specific chapters on Windows Phone, TPL, .net 4.5 … By the way, it’s a delicious mix between .net internals, best practices and recommendations. It’s hard to talk about code optimization without talking about Garbage collection & Jit compilation.  It may not be the best explanation (in terms of details), but it’s certainly one of the easiest to understand. If you’re quite new in .net, it’s mandatory to understand these topics.

The middle of this book is like a catalog. What is a performance cost of throwing exceptions? Class or struct ? Why Enum.ToString() is so CPU-consuming ? How to work with strings efficiently ? Any difference between for & foreach ? …. You may have so many questions and there are so many answers in this book. Each topic is illustrated by code, IL, … and how to diagnose this problem with your new favorite tools (PerfView, CLR Profiler, Dump, …)

What I like also about this book is that it’s not only focused on code. The Performance effort should not be supported by only one guy (you or me) but by the whole team. Having always up-to-date production metrics, automated benchmarks & profiling, educated product owners, is very important for a successful performance strategy.

It will definitively be part of my library about performance, near to others famous books on this topic. I recommend it to every .net developer.

Writing High-Performance .NET Code

Advertisements

The importance of useless Micro-optimization

Micro-optimization is “the process of meticulous tuning of small sections of code in order to address a perceived deficiency in some aspect of its operation (excessive memory usage, poor performance, etc)”

We’ve all seen this kind of debates : Is X faster than Y? Should I have to replace A by B in my code? It’s not specific to any language, but it’s a real question for all developers. Programmers are generally advised to avoid micro-optimization, unless they have a solid justification. Yes, it depends

Most of the time, Micro-optimizations are confirmed by benchmarks: a very specific code section is executed thousands/millions times to illustrate the problem and to confirm initial hypothesis. A is X times slower than B. Of course, in real world applications, we rarely call one piece of code so many times, so this stuff may seem inappropriate. But the trouble is that the extra N-milliseonds is CPU time on the server. A web server could simply be idle waiting for request, processing other requests, … but instead it is busy executing the same inefficient methods over and over. Those N-ms can even become N-s during peaks load.

Improving performance of an application is an endless road. It’s a very time-consuming activity and don’t forget that’s it’s not the core of your Business : Your Boss wants you to deploy new features and not pointless optimizations. It’s very common to spend several hours (days?) to reach your performance goals.

By performance I mean something that limits scalability of your application. It could be CPU, network IO, Memory … You may know that all applications (systems) have throughput limits. Your Job, as a chief performance officer, is to be keep fast response times in all circumstances (unexpected system difficulties, light load/heavy load) and to be far from these limits.

The performance of a code section is a mix between frequency & efficiency. I don’t care to write an inefficient code if it’s rarely used but I’m really concerned by most called operations. Have you already count how many times ToString() is called in your .net project ? We can’t blame someone else for having written un-optimized code that we want to use in our –different- context. For example, .toString() has maybe not been coded to be used as a key for Dictionaries.

Since 10 years of professional programming, I’ve seen serious performance problems. “I don’t understand why it takes 5 sec to generate my page each evening. Everything is cached and I’ve run many benchmarks: all my methods take less than 5ms.” Yes, but these methods are called 100 times while generating your page. Simply speaking, 5 ms is too slow for your context !

Even with a clean architecture it’s sometimes difficult to determine the critical rendering path.  That’s why I’m a big fan of profiling tools like Visual Studio Profiler: they give you a complete overview without changing your application. Collected data during a load test session,  can be precious.

I often see Micro-optimization as a challenge: let me try to significantly improve the performance –and scalability- of your application by changing the fewest lines as possible. If I can’t do this, I’m either not good enough or there are no interesting optimizations.

Examples in .net

A few months ago, I already explained on the Betclic Techblog one bad experience we had with Structuremap and Web Api. To summarize, we’ve significantly reduced CPU usage of a web application, just by splitting IoC bindings into multiple containers.

More recently, I was mandated to do a performance review on a WCF service consuming too much CPU & memory. Without any doubts –thanks to my favorite profiler- , one method is causing several alerts & warnings.

buildmessage

This method is in a base class. Because the project follows the Onion architecture, dependency injection is heavily used here to manage dependencies (at core, service & repository layers). As a consequence to be in a pure stateless world, this method can be invoked several times during each request processing.  The average call rate is approx. 150/sec during peaks load, so this is a good candidate for a micro-optimization.

How to improve this method? It doesn’t look so bad at the first view ….

A first idea could be to optimize string operations. We all know the obvious beginner mistakes of string concatenation. Memory allocations are fast on modern PCs, but they’re far from free.  String.Join()/StringBuilder seems better in this case.

A Second better idea is to remove Enum.ToString(). The type of Legislation/Brand/Platform is enum  The method Enum.ToString() is called implicitly in this code section (during concatenation). An interesting article on codeproject explains the troubles with Enum.ToString().

A few minutes later, I finally produced this extension method (Gist)


public static class EnumExtensions
{
    public static class EnumCache<TEnum>
    {
        public static Dictionary<TEnum, string> Values = new Dictionary<TEnum, string>();
        static EnumCache()
        {
            var t = typeof(TEnum);
            var values = (TEnum[])Enum.GetValues(t);
            var names = Enum.GetNames(t);
            for (var i = 0; i < values.Length; i++)
            {
                Values.Add(values[i], names[i]);
            }           
        }

        public static string Get(TEnum enm)
        {
            return Values[enm];
        }
     }

     public static string AsString<TEnum>(this TEnum enm) where TEnum : struct, IConvertible
     {
         return EnumCache<TEnum>.Values[enm];
     }
}

Let’s run benchmarks it on 50000 iterations (check the gist for the full source code)

vsprofilerenum

consoleoutputenum

Faster and Less allocated memory, Not so bad. (Note : It’s even a little better than the original codeproject article but with less possibilities). For sure, a .net Guru may find a more efficient way but It’s enough for me: I reached my performance goal. We now have an optimized ready-to-use extension method with less than 30 lines of code, that’s 40 times faster. Very well done!

But, We’re ALL WRONG !

Optimizing code means you have to think differently. Simply create a property (eventually lazy),  computed just once per request, and inserted somewhere in the scope. That’s it.

In every project, there are code conventions: this class to manage logging, this one to format date format, this one to translate string… We should be very careful with this kind of helpers, extension methods, utilities; we all have this kind of classes in our projects to factorize pure-technical stuff. Unsupervised usage may lead to serious performance issues.  Never do anything more than once.

Is this micro-optimization a complete waste of time? No at all. We’ve done a lot of interesting things: explore .net internals, run profiling sessions & benchmarks. The final solution is still valid but just not so important in our context. But it could be useful in the future…