我混淆了两个操作:
if(!is_active)
{
do something here...
}
和
if(is_active == false)
{
do something here...
}
哪个比另一个快?如果更快,为什么会更快。
在编译时,它们将生成相同的机器代码。这只是一个语法问题。
来自标准(5.3.1):
逻辑反运算符的操作数!隐式转换To bool (clause 4);如果转换后的操作数为False,否则为False。结果类型为bool
两者是等价的。您可以通过使用-S
选项自己进行测试,该选项将汇编程序输出到file.s
。在amd64上使用gcc,您将获得如下示例
file.cpp:
void f()
{
bool is_active = false;
if(!is_active) { dosomething(); }
if(is_active == false) { dosomething(); }
}
树:
...
movzbl -1(%rbp), %eax
xorl $1, %eax
testb %al, %al
je .L3
call _Z11dosomethingv
.L3:
movzbl -1(%rbp), %eax
xorl $1, %eax
testb %al, %al
je .L2
call _Z11dosomethingv
.L2:
...
您可以很容易地看到两个实例的代码是相同的。
更新到Charles Bailey的注释,包括编译器优化-O2
file.cpp:
extern bool is_active;
void f()
{
if(!is_active) { dosomething(); }
}
void g()
{
if(is_active == false) { dosomething(); }
}
树:
cmpb $0, is_active(%rip)
je .L4
rep
ret
.p2align 4,,10
.p2align 3
.L4:
jmp _Z11dosomethingv
...
cmpb $0, is_active(%rip)
je .L7
rep
ret
.p2align 4,,10
.p2align 3
.L7:
jmp _Z11dosomethingv
这次产生的汇编代码是不同的,但正如预期的那样,这两个if
语句是相同的。
没有比自己尝试更简单的方法了:)编写一个使用这两种方法并测量时间的简单程序。我认为,它可以是编译器和优化特定的。
然而…试图优化这段代码是无用的……你关注的是错误的优化:)
当你的编译器没有把它优化成完全相同的时候,你有一个真正愚蠢的编译器。
但是如果其中一个更快,那么if(!is_active)
,因为它只需要一个ASM INV
命令,而不是LOAD
和CMP
。
未优化,第一个是否定,然后与零比较;第二个是比较,然后是到0的比较。
优化后它们几乎是相同的
这个问题的答案高度依赖于编译器理解代码的能力——编译模板。基本上,您在问相同的二进制问题-变量is_active是否等于0;但你却用两种不同的方式问:
- 是否等于固定值0
智能编译器(以及支持的汇编ISA)不会先执行逻辑上的非,然后再与0进行比较,而是首先与不等于0的值进行比较。
长话短说,假设你的编译器是半智能的,并且ISA支持与不为0的值进行比较;应该是完全一样的
我建议你永远不要使用
if ( is_active == false )
你可以用:
if ( false == is_active )
或if ( !is_active )
但不是为了效率。
初学者常犯的错误是将==
写成=
。(有时我也有这样的错别字)。在前一种情况下,这个错误导致了法律转让。在后一种情况下,编译器会报错,因为你永远不能给false
希望这对你有帮助
这样写是不好的做法:
if(is_active == false)
不要这样做。
关于这样的操作的速度…现在是2013年。: -)