程序的二八法则:“平均而言一个程序的往往将80%的执行时间花在20%的代码上”——Scott Meyers
目录
从牛客上一篇帖子谈起:
首先明确关于内联函数的一些概念:
“编译器隐式的将在类内定义的成员函数当做内联函数”——《Cpp primer》 223页中间部分
内联函数的一些特征:
- 不包括复杂控制语句,如循环语句等
- 规模很小(一般5句以下)
- 使用频繁
- 不能递归等实现
但是刷OJ的时候,大量的class内部成员函数,如下图LeetCode为例,都是inline吗?
显然不是!!!很好理解,大部分都不满足上面提到的inline的几个特征。
“内联函数仅仅是一种请求而没有强制性”——[STROUSTRUP97] 7.1.1节
但是要完全理解上面这句话还要理解inline调用的过程。
内联函数调用机制:
- 通过直接将函数体插入调用处来实现
- 函数的每一个调用都以函数本体替换
代码膨胀:过度热衷inlining会造成程序提及太大,及时拥有虚内存,inline造成的代码膨胀会导致额外的换页行为,降低指令高速缓存装置的击中率,随之带来效率损失。
内联函数的缺点和优点
缺点:
- inline函数无法随着程序库的升级而升级
- 无法调试inline函数,因为怎么可能在一个不存在的函数体内设置断点呢?
优点:
前面说了这么多缺点和注意事项,没有优点吗?当然,存在即合理嘛!
- 为以后的调试和二进制升级带来便利
- 为潜在的代码膨胀问题最小化,是程序的速度提升机会最大化
虚函数、构造函数、析构函数与内联函数
很显然,虚函数是不能被优化成内联函数的
虚函数意味着“等待直到运行是才决定调用哪个函数”
而内联函数意味着“执行前,先将调用动作替换为被调用函数的本体”
很明显相互矛盾!
class中的构造函数,意味着创建一个对象时,每个成员变量都会被自动构造,编译器会进行大量的异常处理,所以明显不符合内联函数小型化的特征,这个优化建议编译器肯定不会接受!
参考
- 《Cpp perime plus》
- 《Effective C++》
- 《Essential C++》