[Effective C++]条款30 inline
条款30 : 透彻了解inlining的里里外外
inline 函数, 多么棒的点子! 本条款将带我们透彻了解inlining的里里外外, 与往常的形式不同, 我会以知识点集的形式把书中对inline的描述列举处理, 可更简单明了的认识inline.
inline的优劣
inline
函数, 看起来像函数, 动作像函数, 却比宏好得多, 调用它们不用蒙受函数调用所带来的额外开销.- 编译器会对
inline
函数执行语境相关最优化, 会提升编译效率. - 如果内存有限, 过度
inlining
会造成程序体积太大. inline
会带来代码膨胀, 进而导致额外的换页行为, 降低高速缓存装置的击中率.- 如果inline函数的本体很小, 编译器针对"函数本体"产出的码可能比针对"函数调用"产出的码更小, 反而会促成与上一条相反的情况, 可以导致较小的目标码和较高的高速缓存装置击中率.
inline
函数无法随程序库的升级而升级, 简单说如果程序库中有一个inline
函数, 如果决定改变该函数, 那么程序库中所有用到该函数的程序就必须重新编译. 如果是non-inline
函数,客户端只需要重新连接就好了, 没有那么大的编译负担, 如果是动态库就更没有了.
inline的特性
-
inline不是一个强制命令, 它只是对编译器的一个申请! 编译器可以加以忽略, 大部分编译器将拒绝太过复杂的函数(含循环, 递归, 长度过长)进行
inlining
. 简而言之, 一个表面看似inline的函数是否真的是inline, 取决于你的建置环境, 主要取决于编译器. -
inline
可以明确提出, 也可以隐喻提出. -
隐喻提出的方式是将函数定义在class定义式中. 这便是为什么很多
class
会将实现简短的函数直接在class
定义式中将声明定义一并给出, 其实就是在方便的前提下还隐喻地使用了inline
函数, 以达到"没有声明任何inline
却处处都是inline
"的效果. -
隐喻
inline
函数通常是成员函数, 也可以是friend
函数. -
所有
virtual
函数与调用virtual
的函数都无法inlining
.virtual
代表着等待运行时判定, 而inline
代表编译时提前替换, 这两种行为是绝对冲突的.
inline的使用
inline
函数通常一定被置于头文件内, 因为大多数建置环境都在编译过程中进行inline
.templates
(泛型类/函数)通常也被置于头文件内, 很多程序员认为泛型函数一定都是inline
, 但这是错误的, template的实例化与inline无关, 不应该这样考量, 还是应该依照代码长度,内容以及环境做具体考量.- 构造函数和析构函数往往是inlining的糟糕候选人, 因为就算它们是空白的, 也有可能在底层被编译器施加很多额外的代码, 例如基类的构造与析构, 这导致它们的实际代码量远比我们看见的要多得多, 令它们
inlining
很有可能会发生代码膨胀. - 一开始先不要将任何函数声明成
inline
, 除非你非常笃定它就是inline
的典型案例, 当你开始关心效率时, 再分析是否可以inlining
.
请记住 :
- 请将大多数的
inlining
限制在小型, 被频繁调用的函数身上. - 通过将函数定义在
class
定义式中实现隐喻inline
.
by 天目中云
原文地址:https://blog.csdn.net/tianmu_sama/article/details/144348213
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!