基于布尔c ++确定值的最快方法

时间:2017-01-09 15:19:56

标签: c++ performance if-statement integer boolean

如果你有一个布尔b和一个int i,那两个例子中哪一个更好?

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

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

在两个示例中,b为真xi-1,否则xi-2。您应该将x声明为i-1并在b为假时递减,还是应该使用第二个示例?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:5)

检查汇编代码,因为优化器会优化,可能是同一解决方案的解决方案。

我可能会将其实现为:

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

为了便于阅读,优化程序很可能会将其视为您的第二个解决方案。