Sorting in C++: 3 times faster than C
radiospiel.org
radiospiel.org
For example, couldn't you just inline the relevant code manually in C? Sure it would be ugly, but it would be fast. Besides, in an absolute sense pretty much any C or C++ code is going to be ugly; if you want pretty code and a compiler that valiantly tries to optimize it, use something like Haskell :P.
An apples to apples comparison would use a handwritten sort routine for C instead of using a library function: STD::sort is closer to writing your own sort and putting in the function calls than calling an external function.
No it's not, that's like saying that using inline operators for vector addition is the same as manually inlineing the code or that manually unrolling a loop is the same as the compiler doing it - by that logic everything is expanded to assembly therefore you should write it in hand optimized assembly to get a "decent comparison" (or LLVM if you want portability) and conclude that assembly is "faster" than C/C++.
Of course there is a reason C++ is faster - it's not magic - it compiles and runs on same hardware - but the point is that it has better abstractions that deliver more for similar code - C provides weak abstractions that don't make this sort of optimization easy for the compiler, so unless you like manually rolling out a sort function every time you need to use it it's actually slower than C++. Same goes for collection libraries, small vectors (eg. 3d vectors), etc. And it's worth pointing out because a lot of people assume low level == fast.
By inlining C++ is able to run just the raw algorithm. On the opposite the C code has a number of indirections
That is a reflection of using qsort rather than rolling your own sort. You could write your own macro that replicates what std::sort does and see better performance in C. That same abstraction can be built in C.If you want to argue that the C++ standard library has more utilities to simplify these optimizations, certainly I will agree. I think, however, that the statement that "sorting in C++ is 3 times faster than C" is an unsubstantiated leap.
Anyway I don't think anyone thinks C++ is magic but I guess the title could be cleaner "sorting with standard libraries C++ 3 times faster".
I would define an apples to apples comparison as "How would a typical C developer write this test? How would a typical C++ developer write this test?"
A typical C developer would use a library function. A typical C++ developer would use the stl.
This was a great article for me because I am actually about to write some very performance intensive data manipulation code that will use sorting and other similar algorithms. I was thinking about doing it in C because I always mentally associate C with performance.
This article is a reminder to me that although I could eventually laboriously hand-tweak the C to be performant, there are things in C++ that will perform better than C without my even having to do much optimization, if any.
By inlining C++ is able to run just the raw algorithm. On the opposite the C code has a number of indirections
The typical C developer is aware of the deficiencies and would write a custom macro to do the sort (I have a whole macro library for many small functions)I agree that the language provides convenience, but the statement that sorting as a concept is faster in C++ than in C seems to be a stretch.
However, that's only true if you let them do their job, ie use link-time optimizations or code inclusion (which is where most of the template performance comes from).
Including the source of qsort() instead of linking against a DLL blob might be enough to make the C code perform as well as the C++ code.
I would be surprised if other high-performance compilers were unable to do so.
I'll update the gist with clang results as I get them built and tested.
Of course you won't see any performance improvements if you only build your executable with LTO, but still link dynamically or statically against a non-LTO capable libc.
As well as `qsort`. It is also not guaranteed to use quick sort.
E.g., here is the BSD qsort: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd...
Here is the glibc one: http://www.umcs.maine.edu/~chaw/200801/capstone/n/qsort.c
However, C compilers are smart enough to transform the latter into the former, but only if you let them.
The C++ code still outperformed the C code, but the ratio dropped from ~2.8 to ~1.4.
40% performance gain is nothing to sneeze at, but it's far less impressive than the sensational 3x from the headline.
The remaining difference is probably due to the choice of algorithm: the GNU STL algorithm is introsort. While it's also a hybrid algorithm based on quicksort, it adds heapsort to the mix, which is known to outperform quicksort on random data.
Optimizing for the second level memory cache means making your data access patterns predictable (the above suggestion helps here, too) and keeping your data compact to get as much use out of each cache line as possible: Do you really need a 64-bit size_t to store an index into an array that will never be larger than a few thousand elements?
It seams that qsort simply executes an order of magnitude more instructions for the same result than std::sort. On the other hand std::sort() code, even if it's faster, it has more branch miss-predictions.
Here [1] are the results if you want to have a look.
Therefore (a-b) would be a better comparison function, if you guarantee it does not overflow.
"I am working as a freelance software architect, IT consultant, ..."