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 ints between 0 and 1000, nth_element takes about 36% longer with the min/max comparison than without.