Аналогично Самый быстрый способ определить, находится ли целое число между двумя целыми числами (включительно) с известными наборами значений , я хочу выяснить, есть ли какое-либо значение (скорее всего, число с плавающей запятой двойной точности) находится между двумя другими значениями (того же типа). Предостережение в том, что я не знаю, какое значение больше другого, и я пытаюсь определить, следует ли мне / как мне следует избегать использования std :: max / min. Вот код, с которым я уже пытался это проверить:
inline bool inRangeMult(double p, double v1, double v2) {
return (p - v1) * (p - v2) <= 0;
}
inline bool inRangeMinMax(double p, double v1, double v2) {
return p <= std::max(v1, v2) && p >= std::min(v1, v2);
}
inline bool inRangeComp(double p, double v1, double v2) {
return p < v1 != p < v2;
}
int main()
{
double a = 1e4;
std::clock_t start;
double duration;
bool res = false;
start = std::clock();
for (size_t i = 0; i < 2e4; ++i) {
for (size_t j = 0; j < 2e4; ++j) {
res = inRangeMult(a, i, j) ? res : !res;
}
}
duration = std::clock() - start;
std::cout << "InRangeMult: " << duration << std::endl;
start = std::clock();
for (size_t i = 0; i < 2e4; ++i) {
for (size_t j = 0; j < 2e4; ++j) {
res = inRangeMinMax(a, i, j) ? res : !res;
}
}
duration = std::clock() - start;
std::cout << "InRangeMinMax: " << duration << std::endl;
start = std::clock();
for (size_t i = 0; i < 2e4; ++i) {
for (size_t j = 0; j < 2e4; ++j) {
res = inRangeComp(a, i, j) ? res : !res;
}
}
duration = std::clock() - start;
std::cout << "InRangeComp: " << duration << std::endl;
std::cout << "Tricking the compiler by printing inane res: " << res << std::endl;
}
На большинстве прогонов я нахожу, что использование std :: min / max по-прежнему самое быстрое (последние прогоны печатают 346, 310 и 324 соответственно), но я не уверен на 100%, что это лучшая тестовая установка, или что я исчерпал все разумные реализации.
Буду признателен за любой вклад с лучшей настройкой профилирования и / или лучшей реализацией.
РЕДАКТИРОВАТЬ: обновлен код, чтобы сделать его менее склонным к оптимизации компилятора.
2-е РЕДАКТИРОВАНИЕ: измененное значение и количество итераций. Результаты за один прогон:
- inRangeMult: 1337
- inRangeMinMaz: 1127
- inRangeComp: 729