if 和三元表达式的区别

在 C 语言层面除了写法以外没什么区别。

int a = 5;

a == 0 ? puts("5") : puts("4");

if (a == 0) {
    puts("5");
} else {
    puts("4");
}

在汇编语言层面上有一些区别,if 倾向于使用条件控制转移j 系列)命令,三元表达式倾向于使用条件数据传输cmov 系列)命令。

void set1(int *a, int *b)
{
    if (*a < *b) {
        *a = *a;
    } else {
        *a = *b;
    }
}

void set2(int *a, int *b)
{
    *a = *a < *b ? *a : *b;
}

O1优化等级编译(经测试 O2, O3 汇编代码相同),反汇编得

a in %rdi, b in %rsi

Dump of assembler code for function set1:
   0x0000000000401166 <+0>:     mov    (%rsi),%eax
   0x0000000000401168 <+2>:     cmp    %eax,(%rdi)
   0x000000000040116a <+4>:     jl     0x40116e <set1+8>
   0x000000000040116c <+6>:     mov    %eax,(%rdi)
   0x000000000040116e <+8>:     retq   
End of assembler dump.

Dump of assembler code for function set2:
   0x000000000040116f <+0>:     mov    (%rdi),%eax
   0x0000000000401171 <+2>:     mov    (%rsi),%edx
   0x0000000000401173 <+4>:     cmp    %edx,%eax
   0x0000000000401175 <+6>:     cmovg  %edx,%eax
   0x0000000000401178 <+9>:     mov    %eax,(%rdi)
   0x000000000040117a <+11>:    retq   
End of assembler dump.

在只进行简单的条件赋值时,条件数据传输命令比条件控制转移要好一些。

  • C 语言层面的代码会更简洁(只要不把三元表达式写得过于复杂);
  • 汇编语言层面,j 需要进行分支预测(也就是是否要进行跳转),预测错误时会损失性能(约 15 ∼ 30 15 \sim 30 1530 个时钟周期),因为跳转意味着执行另一个地方的命令,因此 cmov 性能上会更好。

当然 if 用来进行更复杂的判断和命令是更合适的。

if 、三元表达式和汇编代码之间并不是简单的一对一的关系,倾向于也只是倾向罢了,在实际操作时不必过于在意这些。

参考书籍

Computer Systems: A Programmer’s Perspective, 3/E (CS:APP3e)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值