(1)
if (!cond)
或
(2)
if (cond == false)
好像我看到很多人使用(1)。但是,这不是最优的吗?在C ++中,只要括号中的任何内容都是非零值,if (...)
语句就会计算为true。因此,在(1)中,必须发生的是
cond
然而,在(2)中,所有必须发生的是
cond
是否为零(是否所有位都关闭)现在,检查所有位是否都关闭所花费的时间总是大于或等于检查是否有任何位的时间。因此,问题在于执行逻辑NOT的时间是否平均可以弥补任何差异。
我应该使用哪种优化代码?
答案 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优化的文章,如果我找到了什么,我会编辑这个答案。