我混淆了两种操作:
if(!is_active)
{
do something here...
}
和
if(is_active == false)
{
do something here...
}
哪个比另一个快?如果更快,那为什么会更快。你能用 0 和 1 解释位运算符吗?
我混淆了两种操作:
if(!is_active)
{
do something here...
}
和
if(is_active == false)
{
do something here...
}
哪个比另一个快?如果更快,那为什么会更快。你能用 0 和 1 解释位运算符吗?
编译后,它们将产生相同的机器代码。这只是语法问题。
从标准(5.3.1):
逻辑否定运算符的操作数!隐式转换为 bool(第 4 条);如果转换后的操作数为假,则其值为真,否则为假。结果的类型是 bool。
两者是等价的。您可以使用该-S
选项自行测试,该选项将汇编器输出生成到file.s
. 例如,在 amd64 上使用 gcc
文件.cpp:
void f()
{
bool is_active = false;
if(!is_active) { dosomething(); }
if(is_active == false) { dosomething(); }
}
文件.s:
...
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
文件.cpp:
extern bool is_active;
void f()
{
if(!is_active) { dosomething(); }
}
void g()
{
if(is_active == false) { dosomething(); }
}
文件.s:
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)
,因为它只需要一个 ASMINV
命令而不是LOAD
and CMP
。
没有比自己尝试更简单的方法了 :) 编写简单的程序来使用两者并测量时间。我认为,它可以是编译器和优化特定的。
但是...尝试优化这段代码是没有用的...您专注于错误的优化:)
未优化,第一个是否定,然后是与零的比较;第二个是比较,然后是与零的比较。
优化后它们几乎肯定是一样的。
这个问题的答案很大程度上取决于编译器理解代码的能力——编译模板。基本上,您问的是同一个二进制问题 - 变量 is_active 是否等于 0;但是您以两种不同的方式询问它:
智能编译器(和支持的程序集 ISA)不会执行逻辑非然后与 0 进行比较,而是首先与不等于 0 的值进行比较。
长话短说,假设您的编译器甚至是半智能的,并且 ISA 支持与不为 0 的值进行比较;它应该是完全相同的
我建议你永远不要使用
if ( is_active == false )
相反,您可以使用:
if ( false == is_active )
或者if ( !is_active )
但不是出于效率原因。
初学者的一个常见错误是写==
为=
. (有时我也有这样的错字)。在前一种情况下,这个错误会导致合法分配。在后者中,编译器会抱怨这个错误,因为你永远不能分配任何东西给false
希望这也有帮助:)
像这样写是一种不好的做法:
if(is_active == false)
不要这样做。
关于这种操作的速度......我们在 2013 年。;-)