Лучшее, что я могу придумать это
char a, b, c;
std::cin >> a >> b >> c;
if (((b-a) | (c-a)) & 0x80) {
// a > b || a > c
}
С gcc -O2
это генерирует только один условный переход
40072e: 29 c8 sub %ecx,%eax
400730: 29 ca sub %ecx,%edx
400732: 09 d0 or %edx,%eax
400734: a8 80 test $0x80,%al
400736: 74 17 je 40074f <main+0x3f>
Это оптимизирует использование ограничений входных значений, так как значения не может быть больше чем 26, то вычитание a
из b
даст вам отрицательное значение, когда a > b
, в дополнении 2 вы знаете, что бит 7
будет установлен в этом случае - то же самое относится к c
. I затем ИЛИ оба так, что бит 7
указывает, a > b || a > c
, наконец мы проверим бит 7
на И с 0x80 и веткой на этом.
Обновление: Из любопытства Я приурочил 4 разных способа кодирования. Для генерации тестовых данных я использовал простой линейный конгруэнтный генератор псевдослучайных чисел. Я приурочил его к циклу для 100 миллионов итераций.Я предположил для простоты, что если условие истинно, мы хотим добавить 5 к счетчику, ничего не делать. Я приурочил его, используя g++ (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
на Intel Xeon X5570 @ 2.93GHz
, используя -O2
уровень оптимизации.
Вот код (закомментируйте все, но один из условных вариантов):
#include <iostream>
unsigned myrand() {
static unsigned x = 1;
return (x = x * 1664525 + 1013904223);
}
int main() {
size_t count = 0;
for(size_t i=0; i<100000000; ++i) {
int a = 1 + myrand() % 26;
int b = 1 + myrand() % 26;
int c = 1 + myrand() % 26;
count += 5 & (((b-a) | (c-a)) >> 31); // 0.635 sec
//if (((b-a) | (c-a)) & 0x80) count += 5; // 0.660 sec
//if (a > std::max(b,c)) count += 5; // 0.677 sec
//if (a > b || a > c) count += 5; // 1.164 sec
}
std::cout << count << std::endl;
return 0;
}
Самый быстрый является модификацией по предложению в моем ответе, где мы используем знаковое для создания маски, которая либо 32 1s
или 32 0s
в зависимости от того, является ли условие истинным для false, и используйте это для маскировки добавляемого 5
, чтобы он либо добавлял 5, либо 0. В этом варианте нет ветвей. Время в комментариях к каждой строке. Наиболее медленным было исходное выражение (a > b || a > c)
.
Что и почему именно вы пытаетесь оптимизировать? – delnan
Я сомневаюсь (a * 2)> (b + c) более оптимально, по крайней мере, если я правильно понимаю, что вы хотите улучшить скорость выполнения. – Aleph
Знаете ли вы, что оценка 'a> c' будет пропущена, если' a> b', если это происходит в 'if'? – Zeta