首页 > 其他分享 >if 和三元表达式的区别

if 和三元表达式的区别

时间:2022-10-27 11:55:08浏览次数:60  
标签:puts 区别 int assembler mov eax 三元 rdi 表达式

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

参考书籍

标签:puts,区别,int,assembler,mov,eax,三元,rdi,表达式
From: https://www.cnblogs.com/violeshnv/p/16831716.html

相关文章

  • 关于for-in和for-of的区别
    1.循环数组区别一:forin和forof都可以循环数组,forin输出的是数组的index下标,而forof输出的是数组的每一项的值。constarr=['a','b','c','d']//for........
  • <semaphore.h> 和 <sys/sem.h> 的区别
    <sys/sem.h>为XSI(最初是UnixSystemV)信号量提供接口。这些不是基本POSIX标准的一部分(它们在XSI选项中,主要是为了传统的Unix兼容性),虽然它们还没有被认为是过时的/......
  • dependencies与dependencyManagement的区别
    dependencies与dependencyManagement的区别在我们项目顶层的POM文件中,我们会看到dependencyManagement元素。通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显......
  • 第二十八章 使用 CSP 进行基于标签的开发 - 运行时表达式
    第二十八章使用CSP进行基于标签的开发-运行时表达式运行时表达式CSP文档可能包含在提供页面时(即在运行时)在CSP服务器上运行的表达式。此类表达式使用#(expr)#......
  • GET和POST两种基本请求方法的区别
    GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二。 最直观的区别就是GET把参数包含在URL中,POST通过requestbody传递参数。 你可能......
  • TCP与UDP的区别
    引言网络协议是每个前端工程师都必须要掌握的知识,TCP/IP中有两个具有代表性的传输层协议,分别是TCP和UDP,本文将介绍下这两者以及它们之间的区别。一、TCP/IP网络模型......
  • Spring中过滤器(Filter)和拦截器(Interceptor)的区别和联系
    在我们日常的开发中,我们经常会用到Filter和Interceptor。有时同一个功能。Filter可以做,Interceptor也可以做。有时就需要考虑使用哪一个比较好。这篇文章主要介绍一下,二者......
  • Unix路径化简(注意.和..的区别)
    题目描述简化Unix风格的路径,需要考虑的包括"/../","//","/./"等情况输入描述:Unix风格的路径输出描述:简化后的Unix风格路径示例1输入复制/a/./b/../../c/输......
  • 小菜鸡学习---<正则表达式学习笔记2>
    正则表达式学习笔记2一.修饰符前面我们学习的都是用于匹配的基本的关键的一些表达式符号,现在我们来学习修饰符。修饰符不写在正则表达式里,修饰符位于表达式之外,比如/runo......
  • vue2与vue3的区别
    1、vue使用的是object.defineProperty,vue3使用的是proxy+reflect2、Object.defineProperty(vue2)一次只能监视一个属性,如果要监视一个对象,那么需要遍历这个对象但proxy+......