内联函数(inline) ,提高效率?

1、先说基本原则:

①当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.
②一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!

2、内联一定会增加代码量吗?

不一定!

因为函数调用是需要开销的(函数调用时的参数压栈、栈帧开辟与销毁、以及寄存器保存与恢复等等操作),如果说函数本身的代码量比较小,比函数调用时做的准备工作的代码还要小,那此时如果使用内联的话,肯定比不使用内联的代码量还要小[2]。

不过如果函数的代码量稍大,通常还是会增加代码量的,因为内联函数是在编译阶段被编译器展开在调用处的,多次调用就需要多段重复的代码放在各个调用处。对于非内联函数,只需要保存一份函数体的代码,然后进行调用就好了。所以,在空间上,一般来说使用内联函数会导致生成的可执行文件变大。

3、使用内联函数后对于程序的性能会产生什么影响?

首先,大家都知道现在计算机的存储结构,这里只考虑高速缓存到内存这一部分,从高到低,每一级的访问时间近似以成千倍甚至更高的增加。

其次,高速缓存的大小是很小的(对于我们运行的程序来说),所以我们的数据不可能都被装载到高速缓存中,这就引出了一个命中率的问题。在不命中的时候,就需要向更为下层的存储结构寻找索取目标数据,宝贵的时间也因此不断大幅增加。正如我们前面所说,内联使用不当会导致编译出来的执行程序中的text段比较大,那么相应的能够存活在高速缓存的内容比例也就相对的减小,命中率因此降低,那就会导致程序的性能下降。即因为存储结构的问题,我们过度的使用内联得到了相反的结果[1]。
  对于这一点,思考角度不同,能得到不同的结果。例如,我还可以这么想:
  由于内联后调用函数体内需要执行的代码是相邻的,其执行的代码都在同一 个页面或连续的页面中。如果没有内联,执行到被调用函数时,需要跳到包含被调用函数的内存页面中执行,而被调用函数所属的页面极有可能当时不在物理内存 中。这意味着,内联后可以降低“缺页”的几率,知道减少“缺页”次数的效果远比减少一些代码量执行的效果。另外即使被调用函数所在页面可能也在内存中,但 是因为与调用函数在空间上相隔甚远,所以可能会引起“cache miss”,从而降低执行速度。因此总的来说,内联后程序的执行时间会比没有内联要少。即程序的速度更快,这也是因为内联后代码的空间 “locality”特性提高了[2]。

最后,反过来,内联后,编译器在做优化时,看到的是调用函数与被调用函数连成的一大块代码。即获 得的代码信息更多,此时它对调用函数的优化可以做得更好。

参考:
[1] 内联函数_为什么能提高效率
[2] 内联函数的优缺点
[3] c++ 内联函数 (讲解的TM真好)

猜你喜欢

转载自blog.csdn.net/baidu_35679960/article/details/80845681