C语言关于&与&&运算符
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
C语言关于&与&&运算符
我们知道在很多场景中&和&&通常可以相互代替那么它们到底有什么不同呢
先看一段代码
bool a, b, c;
c = a & b;
使用clang++ -S编译出来的指令如下
movb -5(%rbp), %al # a
andb $1, %al
movzbl %al, %eax
movb -6(%rbp), %cl # b
andb $1, %cl
movzbl %cl, %ecx
andl %ecx, %eax # a & b
cmpl $0, %eax
setne %al
andb $1, %al
movb %al, -7(%rbp) # c
使用clang++ -S -O3编译出来的指令如下
movzbl -1(%rbp), %edx
andb -2(%rbp), %dl
再看一段代码
bool a, b, c;
c = a && b;
其汇编代码为
xorl %eax, %eax
testb $1, -5(%rbp) # a
movb %al, -8(%rbp)
je .LBB2_2
# %bb.1:
movb -6(%rbp), %al # b
movb %al, -8(%rbp)
.LBB2_2:
movb -8(%rbp), %al
andb $1, %al
movb %al, -7(%rbp) # c
反汇编一下
tmp = a;
if(a==1) {
tmp = b;
}
c = tmp & 1;
通过对比两段汇编代码就很清晰了&运算在底层表现为一条指令and而&&运算实际上需要通过分支的方式实现。
那么能否说明&的效率比&&要高呢不一定
我们知道&是与运算例如要得到a & b的值就必须分别求得a和b的值。但是&&通过分支的方式实现要想得到a && b的值其实不必都求出a和b的值如果先求出a的值是0那么就不必再求b了。
再看一段代码
bool funcA() {
}
bool funcB() {
}
int main () {
bool c = funcA() & funcB();
bool d = funcA() && funcB();
}
上述代码中表达式funcA() & funcB() 与 funcA() && funcB() 哪一个效率更高
需要具体分析funcA()和funcB()的返回值分布与复杂度如果funcA()和funcB()复杂度很低并且大部分情况下返回1那么funcA() & funcB()的效率可能会高些如果funcA()和funcB()复杂度较高并且有可能返回0那么funcA() && funcB()会高一些。
另外值得一提的是funcA() && funcB()与funcB() && funcA()哪个效率高
返回0概率 | 复杂性(耗时) | |
---|---|---|
funcA() | a_pz | a_cost |
funcB() | b_pz | b_cost |
funcA() && funcB() 期望耗时为:
a_cost + (1-a_pz) * b_cost
funcB() && funcA() 期望耗时为:
b_cost + (1-b_pz) * a_cost
举个例子
返回0概率 | 复杂性(耗时) | |
---|---|---|
funcA() | 0.9 | 50 |
funcB() | 0.8 | 40 |
funcA() && funcB() 期望耗时为54 funcB() && funcA() 期望耗时为50
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |