【C++】内联函数 ④ ( C++ 编译优化 - 没有 inline 关键字修饰的函数也可能被内联 | C++ 编译器内联限制 | 内联失败的几种情况 )

2023-09-03 21:02:20





一、C++ 编译优化 - 没有 inline 关键字修饰的函数也可能被内联




1、函数内联的不确定性



现在的 C++ 编译器能够进行编译优化 ,

  • 使用了 inline 声明的 内联函数 , 编译器 可能不会允许该函数 进行内联 ;
  • 没有使用 inline 声明的 普通函数 , 如果频繁调用 , 编译器 可能会为了提高执行效率 , 将其内联 ;

内联函数的不确定性 : 编译器内联函数是基于 编译器的优化策略和代码的特性 来决定的 ;

  • 不能保证所有函数都会被内联 ;
  • 即使函数被内联 , 也不能保证 程序的性能 一定会提高 ;

2、C++ 编译器的内联优化


简单且频繁调用的函数 内联大概率成功 , 复杂的函数 大概率内联失败 , 内联成功可能会增加代码的大小 , 也可能会导致程序运行速度变慢 ;

可以通过设置调整 C++ 编译器 的参数 和 优化级别 , 优化编译后的程序运行效果 ;


3、内联优化细节


即使没有使用inline关键字修饰的函数 , C++编译器 根据 函数特性 和 调用频率 , 结合当前的 程序执行效率 和 综合性能 , 决定是否将函数进行内联 ;


内联函数的目的是减少函数调用的开销 , 提高程序的执行效率 ;

编译器在决定是否内联函数时 , 会考虑函数的复杂性 , 大小和调用次数等因素 ;

如果 函数比较简单 且被频繁调用 , 编译器可能会选择将其内联 , 以提高程序的执行效率 ;





二、C++ 编译器内联限制




1、内联失败的几种情况


内联失败的几种情况 : 如果 内联函数 有如下情况 , 即使使用 inline 关键字声明内联函数 , 也是无效的 ;

  • 函数中存在循环 : 内联函数中 不能存在任何形式的 循环语句 , 如 : for / foreach / while / do while 循环 ;
  • 函数中有很多条件判定 : 内联函数中 不能存在过多的条件判定语句 , 条件判断就意味着有无效的指令 , 非常浪费空间 ; 一般是不能超过 20 ~ 30 个条件判断语句 , 具体数目可以通过编译器配置 ;
  • 函数体庞大 : 函数体的代码不能太多 , 函数指令太多 , 在调用位置插入的指令就很多 , 会浪费很多代码空间 ;
  • 对函数进行取地址操作 : 调用函数时 , 尝试获取函数的地址 , 由于 内联函数 是不存在的 , 编译时直接插入到调用位置 , 获取内联函数地址就会导致程序执行失败 , 因此一旦尝试获取内联函数地址 , 内联直接失败 ;
  • 内联函数声明在调用之后 : 由于内联函数不能进行声明操作 , 内联函数的声明与定义必须在一起 , 如果内联函数调用在声明定义之前 , 说明该内联函数进行了单独的声明 , 该函数的内联一定会失败 , 作为普通函数处理 ;

2、内联失败的本质分析


函数中 如果 有循环语句 / 有很多条件判定语句 / 函数体庞大 / 对函数取地址操作 / 单独声明内联函数 , 即使写了 inline 内联函数 , 编译器也不会同意内联请求 ;


内联函数 与 普通函数 对比 , 其优势只是 省去了 函数调用时 的 压栈 / 跳转 / 返回 的开销 ;

如果 函数体 由于过大或执行特殊操作 的执行开销 远大于 压栈 / 跳转 / 返回 的开销 , 此时内联函数 反而会降低程序的整体性能 , 编译器会权衡二者对性能的影响 , 同意 / 否决 函数 的 内联请求 ;

更多推荐

SpringBoot接受请求参数

1.简单参数1.1原始方法说明:获取请求传来的name参数,age参数的值。//简单方式@RestControllerpublicclassRequestController{@GetMapping("/books")publicStringsimpleParam(HttpServletRequestrequest){

Java 基础学习总结(207)—— 具有革命性、未来性、开创新纪元的 JDK 21, 它来了

具有革命性、未来性、开创新纪元的JDK21按照官方的时间计划表,今天终于是要正式GA了:https://openjdk.org/projects/jdk/21/GA,就是我上面框起来的“GeneralAvailability”的缩写,直译成中文,虽然是“普通可用”的意思,但是在软件行业,它就代表正式版。如果对外发布一个

慢SQL治理经验总结

在过去两年的工作中,我们团队曾负责大淘宝技术的慢SQL治理工作,作为横向的数据安全治理平台,如何快速准确地发现部门内所有应用的慢SQL,并进行高效的推动治理,同时覆盖多个开发、生产环境,是一个很大的挑战。以下是一些经验分享,我们通过持续的慢SQL推动治理,有效降低了DB相关的线上问题,极大提高了系统稳定性。关于慢SQL

MVVM 模式、Vue 双向绑定原理

MVVM模式是什么传统的MVC指的是,用户操作会请求服务端路由,路由会调用对应的控制器来处理,控制器会获取数据。将结果返回给前端,页面重新渲染MVVM(Model-View-ViewModel)是一种软件架构模式,用于实现界面(UI)和业务逻辑的分离。他的设计目标是将界面的开发与后端的业务逻辑分离,使得代码易于理解、维

为什么要选择Spring cloud Sentinel

为什么要选择SpringcloudSentinel🍎对比Hystrix🍂雪崩问题及解决方案🍂雪崩问题🍂.超时处理🍂仓壁模式🍂断路器🍂限流🍂总结🍎对比Hystrix在SpringCloud当中支持多种服务保护技术:NetfixHystrixSentinelResilience4J早期比较流行的是Hyst

线性回归网络

李沐大神的《动手学深度学习》,是我入门机器学习的首课,因此在这里记录一下学习的过程。线性回归的从零开始实现线性回归是理解机器学习的基础,它经常用来表示输入和输出之间的关系。线性回归基于几个简单的假设:首先,假设自变量X和因变量y之间的关系是线性的,即y可以表示为X中元素的加权和,这里通常允许包含观测值的一些噪声。下面基

行业报告:视频直播美颜sdk对互联网直播产业的影响与前景

随着互联网直播产业的不断崛起,直播内容的质量和用户体验已成为成功的关键因素之一。本篇报告将深入研究视频直播美颜sdk对互联网直播产业的影响,并探讨其未来的前景。第一章:视频直播美颜sdk的基本概念1.1什么是视频直播美颜SDK?视频直播美颜sdk是一种软件工具包,旨在为互联网直播平台和应用程序提供实时的美颜和图像增强功

笔试面试相关记录(4)

(1)实现防火墙的主流技术有哪些?实施防火墙主要采用哪些技术-服务器-亿速云(yisu.com)(2)chararr[][2]={'a','b','c','d'};printf("%d",*(arr+1));输出的是谁的地址?字符c测试代码如下chararr[][2]={'a','b','c','d'};printf(

java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发

Java版工程项目管理系统SpringCloud+SpringBoot+Mybatis+Vue+ElementUI+前后端分离功能清单如下:首页工作台:待办工作、消息通知、预警信息,点击可进入相应的列表项目进度图表:选择(总体或单个)项目显示1、项目进度图表2、项目信息施工地图:1、展示当前角色权限下能看到的施工地图(

pom的配置策略

dependencyManagement和dependencies区别和联系参考:https://blog.csdn.net/Sunshineoe/article/details/121083505<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://mav

剔除数据中的异常值(python实现)

目录一、3σ原则二、箱线图发现异常值三、boxcox数据变换一、3σ原则该准则仅局限于对正态或近似正态分布的样本数据处理,此外,当测量次数少的情形用准则剔除粗大误差是不够可靠的。异常值是指样本中的个别值,其数值明显偏离其余的观测值。异常值也称离群点,异常值的分析也称为离群点的分析。在进行机器学习过程中,需要对数据集进行

热文推荐