In my last post I discussed cache pressure and how important the cache is for performance. Out of mild curiosity and a bit of boredom, I decided to see how the same code (or near enough) performed in C#. Why C#? A lot of tools are written in C# now, mostly because it’s a nice language with fantastic library support and solid GUI integration. It’s a more productive environment for all those programs that don’t have to run at 60 fps.
Now given how straightforward the test is – sorting an array – I’d expected performance to not differ by much compared to the C++ version. Before I ran this code I was guessing that C# would be maybe 50% slower and at most half the speed than the C++ version. Especially since the sorting should be mostly algorithmically and memory bandwidth bound.
Now for the results.
[EDIT: a number of issues were raised about this test in the comments and elsewhere – here’s my response]
The first issue was to figure out how to actually sort my array in C# – there are a variety of ways to store and sort objects in C# so I first tried the various combinations of Sort & ICompare, Sort<T> & ICompare<T>, using a Comparison function pointer and even C#’s built-in indirect sort Sort(Keys, Items). Let’s set the raw results:
There’s nothing too surprising really – the generic version of Sort<T> is faster than the non-generic one, probably because the CLR can remove dynamic casts or something. Also no surprise that the indirect Sort<Key, Items> version is much, much faster than all the other version – this is what we looked into in my original Cache Pressure post. The only surprise to me is that the IComparer version of the sort is faster than the Comparison function pointer version – I have no idea why, I’d expect both to be nearly identical.
Anyways, we’re here to compare C++ to C#, so lets put the results from our Cache Pressure test side by side with these C# tests:
So here’s the graph of the C++ direct sort vs the generic Sort<T>, IComparer<T> version. In case you can’t read that properly, the C++ version is 10 times faster than the C# version. You can also see that the lines are nice and parallel, so that’s no algorithmic difference in sorting routines, both implementations have the same runtime complexity. We’re seeing 10 times overhead in execution.
Damn! That’s pretty pathetic C#!
And you know what’s even sadder? Here’s a chart of the slow direct C++ sort versus the fastest indirect C# sort:
So C++ still comes out a head, over twice as fast in fact. Considering this is the “fast” C# implementation and the “slow” C++ implementation beats is hands down, you can’t help but be disappointed by C# here. I won’t even bother comparing C#’s sort to C++’s faster indirect sort, we already know the outcome.
So mostly I’ll let the number speak for themselves, the programs I ran are freely available for you to confirm for yourself. I don’t pretend to be any type of C# expert, but my code is pretty much a textbook (or MSDN example) implementation. I even use the exact timing method as the C++ version.
I was very surprised by how much faster C++ ran. I never expected a 10 times difference in performance. This doesn’t mean I’ll stop using C# – it’s still a very productive development environment, especially for GUI tools, which is still often a more important factor than exectuion time. It does mean that I’ll probably think twice about implementing high-performance code in C#.