编译时间和运行态时间交换的优缺点

简介: 编译时间和运行态时间交换的优缺点

前言

(1)前几天,我刷视频无意之间看到一个视频说,sizeof(a++),这个a是会自增吗?

(2)如果有经验的人肯定会说,不会自增,这是常识。那么将这句话转化为汇编之后会发生什么呢?为什么a不会进行自增呢?


将sizeof(a++)转换为汇编

(1)既然我们要探究为什么sizeof(a++)中的a不会进行自增,那么最好的办法就是,将C语言转换成汇编,看看最终执行效果


(2)这是为什么呢?我去查阅了C语言标准,其中有这么一段话:

When applied to an expression, sizeof does not evaluate the expression (i.e. the expression is an unevaluated operand) (since C++11), and even if the expression designates a polymorphic object, the result is the size of the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed. Temporary materialization, however, is (formally) performed for prvalue arguments: the program is ill-formed if the argument is not destructible. (since C++17)

翻译结果:当应用于表达式时,sizeof不计算表达式 (即表达式是未计算的操作数) (C++11 起),并且即使表达式指定多态对象,结果也是表达式的静态类型的大小。不执行左值到右值、数组到指针或函数到指针的转换。然而,临时物化(正式)是对纯右值参数执行的:如果参数不可破坏,则程序是格式错误的。 (自 C++17 起)

(3)由此可见,C语言标准决定了sizeof之后的式子是不会进行任何的计算的。


为什么sizeof后面的式子不进行计算

用编译器的时间换运行态的时间

(1)这个时候可能有人就会有疑问了。为什么sizeof后面的式子不进行计算呢?

(2)通过和大佬们交流,我得知了一个名词,叫做用编译器的时间换运行态的时间。

(3)这个时候可能有人就有疑惑了。编译器时间是什么呢?运行态时间又是什么呢?我在stack overflow上找到了非常好的解释。

<1>编译时:您(开发人员)编译代码的时间段。

<2>运行时间:用户运行您的软件的时间段。

(4)当你调用sizeof 的时候,核心目的是为了知道这个变量所占几个字节。那么,==一个数据,进行自增或者自减,是不会影响到他的类型的,他占据几个字节也不会有影响。==所以为了提高代码执行速度,我们可以只进行判断变量a 的所占字节即可,他的运算是可有可无的。

时间交换可能会产生的不良后果

(1)现在,我们知道了可以使用编译器时间来换取运行时间,来提高用户体验,那么这样做,真的就非常完美了吗?

(2)答案肯定是不,为什么呢?因为,想单片机程序,如果我想让一个单片机进行一个1ms的延时。于是我就让变量a进行不断的自增,最终实现延时效果。

 //假设这是一个延时1ms的程序
void delay(void)
{
  int a;
  for(a=0;a<50000;a++);
}


(3)但是,如果是玩过MSP430的同学就会发现,不对,有问题。这个并没有延时效果,我们会需要调整编译器优化等级才可能出现延时效果。

(4)这是为什么呢?原因很简单,如果你编译器优化等级过高,而编译器发现for(a=0;a<50000;a++);这个语句什么都没做,可能就会放弃掉这个语句。最终导致无法产生想要的延时效果。

(5)编译器除了放弃一些认为不用的程序以外,还做了什么吗?举个例子,假如一个程序里面有一个运算式子:a = 2+2+4 ,那么编译器会直接将2+2+4计算出来,并且将8传给a。这样就能够降低运行状态的时间,提高用户体验。


总结

(1)sizeof(a++)这个运算式子算是编译器时间换运行态时间的一种方式,这样做能够提高用户体验。

(2)但是,有可能程序员一开始的目标就是要用来延时的,所以容易产产生负面效果。

(3)因此,我们应该对这个有充分的了解。根据需求做决定。

目录
相关文章
|
3月前
|
监控 Linux
在Linux中,有⼀个脚本运行时间可能超过2天,如何做才能使其不间断的运行,而且还可以随时观察脚本运行时的输出信息?
在Linux中,有⼀个脚本运行时间可能超过2天,如何做才能使其不间断的运行,而且还可以随时观察脚本运行时的输出信息?
|
3月前
|
算法 Java
JDK版本特性问题之想控制 G1 垃圾回收器的并行工作线程数量,如何解决
JDK版本特性问题之想控制 G1 垃圾回收器的并行工作线程数量,如何解决
|
5月前
|
Java 程序员
Java多线程编程是指在一个进程中创建并运行多个线程,每个线程执行不同的任务,并行地工作,以达到提高效率的目的
【6月更文挑战第18天】Java多线程提升效率,通过synchronized关键字、Lock接口和原子变量实现同步互斥。synchronized控制共享资源访问,基于对象内置锁。Lock接口提供更灵活的锁管理,需手动解锁。原子变量类(如AtomicInteger)支持无锁的原子操作,减少性能影响。
46 3
|
4月前
|
敏捷开发 测试技术 持续交付
编码过程中有效地管理时间和精力,避免陷入无休止的调试循环
编码过程中有效地管理时间和精力,避免陷入无休止的调试循环
|
Go 数据库
sync.Once-保证运行期间的某段代码只会执行一次
sync.Once-保证运行期间的某段代码只会执行一次
82 0
|
6月前
|
Linux Shell vr&ar
进程从代码到二进制到运行时的过程
【4月更文挑战第18天】Linux系统中二进制程序的格式,介绍了ELF(Executable and Linkable Format)格式。
|
6月前
在程序运行过程中,线程的状态是什么?进来看看就通透了
在程序运行过程中,线程的状态是什么?进来看看就通透了
49 0
|
开发工具 git
STM32:定时器定时中断软件篇(内含:1.实验现象+2.代码编写思路+3.代码部分+4.定时器常用库函数详解)
STM32:定时器定时中断软件篇(内含:1.实验现象+2.代码编写思路+3.代码部分+4.定时器常用库函数详解)
605 0
STM32:定时器定时中断软件篇(内含:1.实验现象+2.代码编写思路+3.代码部分+4.定时器常用库函数详解)
|
存储 Java 编译器
JVM特点,基础结构与执行周期
虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。
181 0
JVM特点,基础结构与执行周期
|
IDE 物联网 测试技术
项目实战:Qt并发服务器通讯,受同一时刻最大线程数限制(笔者本本同一时刻600多)
项目实战:Qt并发服务器通讯,受同一时刻最大线程数限制(笔者本本同一时刻600多)
项目实战:Qt并发服务器通讯,受同一时刻最大线程数限制(笔者本本同一时刻600多)