内联扩展 inline expansion An Inline Function is As Fast As a Macro 与宏的比较
让编译器直接将完整的函数体插入到每一个调用该函数的地方,从而提高函数调用的运行速度。
优秀的JIT编译器会通过侦测运行信息,仅将需要频繁运行的瓶颈部分进行编译,从而大大削减编译所需的时间。
而且,利用运行时编译,可以不用考虑连接的问题而积极运用内联扩展,因此在某些情况下,运行速度甚至可以超过C++。
https://gcc.gnu.org/onlinedocs/gcc/Inline.html
https://zh.wikipedia.org/wiki/内联函数
在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,因为过多的比较复杂的函数进行内联扩展将带来很大的存储资源开支。另外还需要特别注意的是对递归函数的内联扩展可能引起部分编译器的无穷编译。
设计内联函数的动机
内联扩展是一种特别的用于消除调用函数时所造成的固有的时间消耗方法。一般用于能够快速执行的函数,因为在这种情况下函数调用的时间消耗显得更为突出。这种方法对于很小的函数也有空间上的益处,并且它也使得一些其他的优化成为可能。
没有了内联函式,程式员难以控制哪些函数内联哪些不内联;由编译器自行决定是否内联。加上这种控制维度准许特定于应用的知识,诸如执行函式的频繁程度,被利用于选择哪些函数要内联。
此外,在一些语言中,内联函数与编译模型联系紧密:如在C++中,有必要在每个使用它的模块中定义一个内联函数;与之相对应的,普通函数必须定义在单个模块中。这使得模块编译独立于其他的模块。
与宏的比较
通常,在C语言中,内联展开的功能由带参宏(Macros)在源码级实现。内联提供了几个更好的方法:
- 宏调用并不执行类型检查,甚至连正常参数也不检查,但是函数调用却要检查。
- C语言的宏使用的是文本替换,可能导致无法预料的后果,因为需要重新计算参数和操作顺序。
- 在宏中的编译错误很难发现,因为它们引用的是扩展的代码,而不是程序员键入的。
- 许多结构体使用宏或者使用不同的语法来表达很难理解。内联函数使用与普通函数相同的语言,可以随意的内联和不内联。
- 内联代码的调试信息通常比扩展的宏代码更有用。
语言支持
C++,C99. C11和GNU C都支持内联函数,然而1989 ANSI C,这个最被广泛使用的C标准却不支持。在Ada中,关键字“pragma”可以用来声明内联。其他的大部分编程语言,包括Java和函数式语言,不支持内联函数,但他们的编译器常常进行强制性的内联扩展。不同的编译器在内联扩展上有处理不同复杂程度函数的能力。主流的C++编译器如Visual C++和GCC提供了一个选项来自动内联任何一个合适的函数,即使它们没有被声明为内联函数。
内联函数在C++中的写法如下:
inline int max (int a, int b)
{
if (a > b)
return a;
else
return b;
}
a = max (x, y); // 等价于 "a = (x > y ? x : y);"
内联函数的不足
除了通常使用内联扩展可能带来的问题,作为一种编程语言特性的内联函数也可能并没有看起来那么有效,原因如下:
- 通常,编译器比程序设计者更清楚对于一个特定的函数是否合适进行内联扩展;一些情况下,对于程序员指定的某些内联函数,编译器可能更倾向于不使用内联甚至根本无法完成内联。
- 对于一些开发中的函数,它们可能从原来的不适合内联扩展变得适合或者倒过来。尽管内联函数或者非内联函数的转换易于宏的转换,但增加的维护开支还是使得它的优点显得更不突出了。
- 对于基于C的编译系统,内联函数的使用可能大大增加编译时间,因为每个调用该函数的地方都需要替换成函数体,代码量的增加也同时带来了潜在的编译时间的增加。
内联扩展 inline expansion An Inline Function is As Fast As a Macro 与宏的比较的更多相关文章
- 内联扩展 inline expansion
让编译器直接将完整的函数体插入到每一个调用该函数的地方,从而提高函数调用的运行速度. 优秀的JIT编译器会通过侦测运行信息,仅将需要频繁运行的瓶颈部分进行编译,从而大大削减编译所需的时间. 而且,利用 ...
- 内联函数 —— C 中关键字 inline 用法解析
一.什么是内联函数 在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗. 为了解决这个问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放 ...
- 重构改善既有代码设计--重构手法02:Inline Method (内联函数)& 03: Inline Temp(内联临时变量)
Inline Method (内联函数) 一个函数调用的本体与名称同样清楚易懂.在函数调用点插入函数体,然后移除该函数. int GetRating() { return MoreThanfiveLa ...
- 【转载】内联函数 —— C 中关键字 inline 用法解析
转载地址:https://blog.csdn.net/zqixiao_09/article/details/50877383 一.什么是内联函数 在C语言中,如果一些函数被频繁调用,不断地有函数入栈, ...
- C++ inline(内联什么时候使用)
(1)什么是内联函数?内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内. (2)为什么要引入内联函数?当然,引入内联函数的主要目的是:解决程序中函数调用的效率问题.另外,前面我们讲到 ...
- (inline)内联函数在IOS开发中的使用
今天在阅读YYKit源码(https://github.com/ibireme/YYKit.git)时发现在YYKitMacro.h组件中大量使用的内联函数,例如此文件中的一个函数 static in ...
- 内联函数 inline 漫谈
内联函数存在的结论是: 引入内联函数是为了解决函数调用效率的问题 由于函数之间的调用,会从一个内存地址调到另外一个内存地址,当函数调用完毕之后还会返回原来函数执行的地址.函数调用会有一定的时间开销,引 ...
- c++内联函数解析(inline)
一.基本定义 inline是C++语言中的一个关键字,可以用于程序中定义内联函数,inline的引进使内联函数的定义更加简单.说到内联函数,这里给出比较常见的定义,内联函数是C++中的一种特殊函数,它 ...
- C++ 内联函数 inline关键字
inline 关键字主要功能是为了 代替掉 宏代码片段. 在C++中使用关键字inline关键字声明内联函数. inline int fun(int a,int b) { return a < ...
随机推荐
- Kafka Eagle 管理平台
Kafka-Eagle简介 源代码地址:https://github.com/smartloli/kafka-eagle Kafka Eagle是什么 Kafka Eagle是一款用于监控和管理Apa ...
- Loki 初体验
Loki 是什么 Loki 是 Grafana Lab开发的一套日志系统,使用Go语言实现.根据官方的介绍, Loki,高可用性,多租户的日志聚合系统,受到Prometheus的启发.它的设计非常经济 ...
- 将后端返回的数据在jsp中拼接成table列表
//先下载jquery js文件 放入项目中 jsp文件内容 <%@ page language="java" pageEncoding="UTF-8"% ...
- [LeetCode]501. Find Mode in Binary Search Tree二叉搜索树寻找众数
这次是二叉搜索树的遍历 感觉只要和二叉搜索树的题目,都要用到一个重要性质: 中序遍历二叉搜索树的结果是一个递增序列: 而且要注意,在递归遍历树的时候,有些参数如果是要随递归不断更新(也就是如果递归返回 ...
- 深入理解Redis系列之持久化
redis持久化配置 redis.conf // RDB配置 save 900 1 save 300 10 save 60 10000 // AOF配置 appendonly yes //AOF三种同 ...
- FFT原理及C++与MATLAB混合编程详细介绍
一:FFT原理 1.1 DFT计算 在一个周期内的离散傅里叶级数(DFS)变换定义为离散傅里叶变换(DFT). \[\begin{cases} X(k) = \sum_{n=0}^{N-1}x(n)W ...
- 【SpringBoot1.x】SpringBoot1.x 检索
SpringBoot1.x 检索 文章源码 概念 Elasticsearch 是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本.数字.地理空间.结构化和非结构化数据.Elasticse ...
- 用js实现打印九九乘法表
用js在打印九九乘法表 思考 在学习了流程控制和条件判断后,我们可以利用js打印各式各样的九九乘法表 不管是打印什么样三角形九九乘法表,我们都应该找到有规律的地方,比如第一列的数字是什么规律,第一行的 ...
- Ubuntu_Gedit配置
Ubuntu_Gedit配置 为了换Ubuntu的时候能够更加方便,不用再用手重新打一遍代码,丢几个Gedit配置-- External Tools gdb compile (F2) #!/bin/s ...
- 【Oracle】10.2.0.1升级到10.2.0.5
升级数据库到10.2.0.5 因是测试环境,不需要备份:如是生产系统,建议进行全备份后再进行升级操作,预防数据丢失造成不必要的影响. 步骤: 上传并解压补丁,安装前准备,安装补丁,预升级检查, ...