Я ожидал, что std::ranges::minmax будет быстрее, чем использование std::ranges::min, а затем std::ranges::max, поскольку следует выполнить один обход вместо двух (как обсуждалось там: Зачем нужен std::minmax_element?).
Но, на мой взгляд, сюрприз, если я не ошибся, std::ranges::minmax кажется медленнее (по крайней мере, на https://quick-bench.com/).
Чем можно объяснить такое поведение? Это «ошибка», которую следует исправить в будущем?
Вот мой стенд: https://quick-bench.com/q/ohUNvsA5Egwl0oxgUFzChlD-2C8
И мои фрагменты:
Код: Выделить всё
void use_minmax(std::vector const& vec) {
auto const [min, max] = std::ranges::minmax(vec);
benchmark::DoNotOptimize(min);
benchmark::DoNotOptimize(max);
}
Код: Выделить всё
void use_min_and_max(std::vector const& vec) {
auto const min = std::ranges::min(vec);
auto const max = std::ranges::max(vec);
benchmark::DoNotOptimize(min);
benchmark::DoNotOptimize(max);
}
Примечание: простая реализация для одного прохода на самом деле быстрее (хотя и не в два раза быстрее): https://quick-bench.com/q/lOJq7Eu913Qx1evPz4ICCiC_OaA
Примечание: I также протестируйте на локальном компьютере с -march=native и, хотя это меняет рейтинг, это не меняет общего вывода: версия с одной функцией медленнее, чем версия с двумя функциями.
[EDIT] вот более исчерпывающее сравнение, включая наивную реализацию: https://quick-bench.com/q/5_ibei8zFUM1y9RtM3k5EgnNtwU
Что касается всех содержательных комментариев о реализации clang, вот также тест gcc: https://quick-bench.com/q/aAJ_AgZbAMmW5q5z3XEcchEQ69Q
Он не работает лучше, хотя он более совместим с двумя версиями обхода.
В соответствии с принципом нулевых накладных расходов этот стенд беспокоит меня.
[EDIT2] благодаря комментариям Питера Кордеса, вот тест с int:
- gcc: https://quick-bench.com/q/kyL4woieCXme5AvS_qCOCxWmjZM
- clang: https://quick-bench.com/q/bptxi21holDI0q5INiSsrsKVN5g
Подробнее здесь: https://stackoverflow.com/questions/798 ... drangesmax
Мобильная версия