What's the most efficient way to extract min, max & median from a vector
Use std::nth_element
to partition which yields the median, then std::min_element
in the left half and std::max_element
in the right one.
If you need it to be faster than that then roll your own version based on std::nth_element
.
Another option is to specify a custom comparison for std::nth_element
, which captures the min and max. It will likely end up doing a lot more comparisons and branches, so this might be slower on some specific hardware, possibly depending on how much of your data is cached etc., so - as always - benchmark if you've reason to care, but for a non-empty vector
a
the technique looks like this:
int min = a[0], max = a[0];
std::nth_element(a.begin(), a.begin() + n, a.end(),
[&](int lhs, int rhs) {
min = std::min(min, std::min(lhs, rhs));
max = std::max(max, std::max(lhs, rhs));
return lhs < rhs;
});
For what little it's worth, on my (~10yo i5-660) HTPC using GCC 7.4 with 1 million random int
s between 0 and 1000, nth_element
takes about 36% longer with the min/max comparison than without.