2017-01-09 8 views
6

Если у вас есть boolean b и int i, какой из двух примеров лучше?Самый быстрый способ определить значение на основе boolean C++

int x = i-1; 
if(!b)x--; 

или

int x; 
if(b)x = i-1;else x = i-2; 

В обоих примерах, если b истинно x является i-1, иначе x является i-2. Должен ли вы объявить x как i-1 и декретировать, если b является ложным или следует использовать второй пример?

+9

Бесконтактная версия 'x = i - 2 + b;' –

+4

Шансы высоки, что если вы скомпилируете в выпуске, компилятор выдаст один и тот же код в любом случае – user

+1

Почему вы даже спрашиваете? Микрооптимизация неосведомлена. –

ответ

10

Я был бы удивлен, если бы компиляторы не оптимизировали обе версии к одной и той же оптимальной сборке. Не тратьте время на эту микро-оптимизацию, если вы не можете доказать, что они важны с использованием профилировщика.

Чтобы ответить на ваш вопрос: это не имеет значения. Вот сравнение «сгенерированной сборки» на 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:

Godbolt comparison

+0

Укажите, какие флаги вы использовали (-O3?) –

+0

@IvanRubinson: он находится на ссылке godbolt, я использовал '-Ofast'. –

+0

Спасибо!Я спрашивал только потому, что мне было любопытно. – theo2003

5

Проверьте код сборки, так как оптимизатор будет оптимизировать, возможно, и ваши решения того же раствора.

я бы, вероятно, реализовать его как:

int x = (b) ? i - 1 : i - 2; 

Для удобства чтения и высокой вероятно оптимизатор сделает его равным в качестве второго решения.

+3

Я бы написал 'int x = i - b? 1: 2; 'не говоря уже о' i' дважды – Slava

+1

Я бы написал 'const int x = i - 2 + !! b', чтобы вообще не иметь никакого ветвления. –

+0

Будет ли 'int x = i - 2 + b' работать? – theo2003