在 C 语言层面除了写法以外没什么区别。
int a = 5;
a == 0 ? puts("x") : puts("z");
if (a == 0) {
puts("x");
} else {
puts("z");
}
在汇编语言层面上有一些区别,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 \sim 30\) 个时钟周期),因为跳转意味着执行另一个地方的命令,因此cmov
性能上会更好。
当然 if
用来进行更复杂的判断和命令是更合适的。
if
、三元表达式和汇编代码之间并不是简单的一对一的关系,倾向于也只是倾向罢了,在实际操作时不必过于在意这些。
参考书籍
原文地址:http://www.cnblogs.com/violeshnv/p/16831716.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性