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

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

前言

(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)因此,我们应该对这个有充分的了解。根据需求做决定。

目录
相关文章
|
10月前
|
云安全 监控 负载均衡
游戏运行只会占用到服务器里面一个核心使用,其他核心不工作,是什么问题
游戏运行只占用服务器的一个核心,而其他核心不工作,可能有多种原因。以下分享一些常见的原因和处理的方案
|
7月前
|
C++
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
71 0
|
7月前
|
监控 Linux
在Linux中,有⼀个脚本运行时间可能超过2天,如何做才能使其不间断的运行,而且还可以随时观察脚本运行时的输出信息?
在Linux中,有⼀个脚本运行时间可能超过2天,如何做才能使其不间断的运行,而且还可以随时观察脚本运行时的输出信息?
|
10月前
|
存储 缓存 Java
揭秘计算机指令执行的神秘过程:CPU内部的绝密操作
本文介绍了计算机指令和CPU如何执行指令。它解释了计算机指令可以被视为CPU所理解的语言,不同的CPU支持不同的指令集。文中重点介绍了MIPS指令集作为示例。同时,还描述了CPU的内部处理过程,包括控制单元、算术逻辑单元和数据单元。文章最后讨论了CPU和内存之间通过地址和数据总线进行的数据传输。
328 1
|
Unix Linux 调度
【操作系统篇】第四篇——线程(概念,实现方式,模型,状态与转换)
【操作系统篇】第四篇——线程(概念,实现方式,模型,状态与转换)
【操作系统篇】第四篇——线程(概念,实现方式,模型,状态与转换)
|
存储 Java 编译器
JVM特点,基础结构与执行周期
虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。
196 0
JVM特点,基础结构与执行周期
|
IDE 物联网 测试技术
项目实战:Qt并发服务器通讯,受同一时刻最大线程数限制(笔者本本同一时刻600多)
项目实战:Qt并发服务器通讯,受同一时刻最大线程数限制(笔者本本同一时刻600多)
项目实战:Qt并发服务器通讯,受同一时刻最大线程数限制(笔者本本同一时刻600多)
|
存储 Apache 流计算
Flink 1.8.0中的状态生存时间特性:如何自动清理应用程序的状态
在本文中,我们将讨论引入状态生存时间特性的动机并讨论其相关用例。此外,我们还将演示如何使用和配置该特性。同时,我们将会解释Flink如何借用状态生存时间特性在内部管理状态,并对Flink 1.8.0中该功能引入的相关新特性进行一些展示。本文章最后对未来的改进和扩展作了展望。
1615 0
|
缓存 前端开发 rax
浅析CPU结构对程序的影响以及熔断原理
## CPU 结构简介 ### CPU 指令结构 * 下表列出了CPU关键技术的发展历程以及代表系列,每一个关键技术的诞生都是环环相扣的,处理器这些技术发展历程都围绕着如何不让“CPU闲下来”这一个核心目标展开。
2506 0

相关实验场景

更多