qsort vs. std::sort
When writing high performance code, there are pretty well two options: C and C++.
- C is essentially a portable wrapper around assembly. You can tell exactly how much every action costs, where memory is allocated, and where it is freed. Nothing is hidden. However, because of this direct control, writing C code is very tedious and error prone.
- C++ is a bit higher level. You give up some control in exchange for ergonomics. For example, returning a
vector
from a function is the difference between an O(1) and O(n) operation, depending on if the compiler implements return value optimization. However, C++ templates give the compiler more type information, which it can sometimes use to generate faster code.
A classic example of when C++ outperforms C is sorting. In item 46 of his book Effective STL, Scott Meyers claims that std::sort
can outperform qsort
by up to 670% because C++ will inline the comparison function during template instantiation. Let's see how they compare with sorting a vector of a million random integers. Writing and measuring accurate benchmarks is difficult, so we're going to let the Nonius framework do it for us.
// sort.cpp
// qsort
static int
// std::sort with no inlining
;
// std::sort with inlining
;
static std::vector<int>
// generate a vector of a million random integers
constexpr size_t size = 1'000'000;
static const auto rand_vec = ;
;
;
;
Let's compile this bad boy.
# Apple Clang 8.0.0
# Note that Nonius has a dependency on Boost
Nonius prints out quite a lot of information, so I'll summarize the most important bits.
qsort 253 ms +/- 8 ms
std::sort noinline 137 ms +/- 6 ms
std::sort inline 88 ms +/- 5 ms
With no inlining, std::sort
is already 1.8x faster than qsort
. I am unsure why this is, it could be from differences in algorithms. Inlining bumps this up to 2.9x faster: an impressive speedup.