检查条件是否为真更快?

时间:2014-05-29 17:52:50

标签: c++ optimization

(1)

if (!cond)

(2)

if (cond == false)

好像我看到很多人使用(1)。但是,这不是最优的吗?在C ++中,只要括号中的任何内容都是非零值,if (...)语句就会计算为true。因此,在(1)中,必须发生的是

  • cond
  • 上执行逻辑NOT
  • 检查结果是否为非零(是否有任何位)

然而,在(2)中,所有必须发生的是

  • 检查cond是否为零(是否所有位都关闭)

现在,检查所有位是否都关闭所花费的时间总是大于或等于检查是否有任何位的时间。因此,问题在于执行逻辑NOT的时间是否平均可以弥补任何差异。

我应该使用哪种优化代码?

4 个答案:

答案 0 :(得分:7)

使用clang -O3进行测试:

int main () {
    int i;
    cin >> i;

    if (i == 0)
    return -1;
}

制作

leaq    4(%rsp), %rsi
movl    $_ZSt3cin, %edi
callq   _ZNSirsERi
cmpl    $1, 4(%rsp)
sbbl    %eax, %eax
popq    %rdx
ret

,而

int main () {
    int i;
    cin >> i;

    if (!i)
    return -1;
}

产生

leaq    4(%rsp), %rsi
movl    $_ZSt3cin, %edi
callq   _ZNSirsERi
cmpl    $1, 4(%rsp)
sbbl    %eax, %eax
popq    %rdx
ret

所以没有任何区别。

答案 1 :(得分:1)

优化不是问题。任何值得使用的编译器都会生成完全相同的结果。问题在于代码的可读性。 if(x == true)if(x == false)(对我和许多其他程序员)的可读性远低于if(x)if(!x)

当它演变成像if((a != b) == false)这样的东西时,尤其如此。代码确实会随着时间的推移而发展。

答案 2 :(得分:0)

在任何现代编译器中,生成的程序集似乎不太可能不同。实际上,如果现代编译器发现它可以保证在一个分支上进行评估,那么现代编译器将优化整个if语句。当然,您可以随时检查装配。

最后,您应该在这种情况下优化源代码的可理解性,而不是优化后编译。

答案 3 :(得分:0)

我可以告诉你if语句设计的拇指规则。

我总是在evaluated-to-true块中放入我认为在我的使用中大部分时间都会发生的代码。

我相信编译器会在if命令之后立即将evaluated-to-true语句cmp块放在程序集中(除非它有关于程序的更多信息,然后它会优化它)不同)。

执行else块(分支)后,现代CPU将对性能产生轻微影响。

但是对于底线 - 如果你的程序不符合高端性能要求,你就不应该关心 - 两者都是一样的。如果您关心,请将代码的公共部分放在evaluate-to-true表达式块中(紧跟if语句之后)。

我会花一些时间搜索一些关于分支机构的编译器/ CPU优化的文章,如果我找到了什么,我会编辑这个答案。