std::ranges::minmax_element slower than std::ranges::min_element and std::ranges::max_element

3 weeks ago 16
ARTICLE AD BOX

I benchmarked both solutions for finding the smallest and largest values within a range.

I would have expected std::ranges::minmax_element to be faster than using std::ranges::min_element then std::ranges::max_element as a single traversal should be made instead of two (as discussed there: Why need std::minmax_element?).

But to my surprise, if I didn't made a mistake, std::ranges::minmax_element seems slower (at least on https://quick-bench.com/).

What could explain this behavior? Is this a "bug" that should be fixed in the future?

Here is my bench: https://quick-bench.com/q/ohUNvsA5Egwl0oxgUFzChlD-2C8

And my snippets:

void use_minmax(std::vector<double> const& vec) { auto const [min, max] = std::ranges::minmax(vec); benchmark::DoNotOptimize(min); benchmark::DoNotOptimize(max); } void use_min_and_max(std::vector<double> const& vec) { auto const min = std::ranges::min(vec); auto const max = std::ranges::max(vec); benchmark::DoNotOptimize(min); benchmark::DoNotOptimize(max); }

According to the documentation, std::ranges::minmax complexity is in the order of 1.5 times the size of the range (at worst) while using std::ranges::min and std::ranges::min is always in the order of 2 the size of the range. It implies that the actual number of operations for std::ranges::minmax is at worse: cx1.5xN where c would be surprisingly large.

NB: the naive implementation for single pass is actually faster (though not twice faster): https://quick-bench.com/q/lOJq7Eu913Qx1evPz4ICCiC_OaA


[EDIT] here is a more exhaustive comparison, including the naive implementation: https://quick-bench.com/q/5_ibei8zFUM1y9RtM3k5EgnNtwU

With respect to all insightful comments about clang implementation, here is also the gcc benchmark: https://quick-bench.com/q/aAJ_AgZbAMmW5q5z3XEcchEQ69Q

It does not make a better work, though it is more consistent with respect with the two traversal versions.

In vertu of the Zero-overhead principle, this bench is bothering me.

Read Entire Article