Я был бы удивлен, если бы компиляторы не оптимизировали обе версии к одной и той же оптимальной сборке. Не тратьте время на эту микро-оптимизацию, если вы не можете доказать, что они важны с использованием профилировщика.
Чтобы ответить на ваш вопрос: это не имеет значения. Вот сравнение «сгенерированной сборки» на gcc.godbolt.org с -Ofast
.
volatile int state0;
volatile void f0(volatile int i, volatile bool b)
{
int x;
if(b)x = i-1;else x = i-2;
state0 = x;
}
... компилируется в ...
f0(int, bool): # @f0(int, bool)
mov dword ptr [rsp - 4], edi
mov byte ptr [rsp - 5], sil
movzx eax, byte ptr [rsp - 5]
or eax, -2
add eax, dword ptr [rsp - 4]
mov dword ptr [rip + state0], eax
ret
volatile int state1;
volatile void f1(volatile int i, volatile bool b)
{
int x = i-1;
if(!b)x--;
state1 = x;
}
... компилируется в ...
f1(int, bool): # @f1(int, bool)
mov dword ptr [rsp - 4], edi
mov byte ptr [rsp - 5], sil
mov eax, dword ptr [rsp - 4]
movzx ecx, byte ptr [rsp - 5]
or ecx, -2
add ecx, eax
mov dword ptr [rip + state1], ecx
ret
Как вы можете видеть, разница минимальна и, скорее всего, исчезнет, когда компилятору разрешено более агрессивно оптимизировать, удалив volatile
.
Вот подобное сравнение в виде изображения, используя -Ofast -march=native -ffast-math
:
Бесконтактная версия 'x = i - 2 + b;' –
Шансы высоки, что если вы скомпилируете в выпуске, компилятор выдаст один и тот же код в любом случае – user
Почему вы даже спрашиваете? Микрооптимизация неосведомлена. –