一、什么是内联函数
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
内联函数一般要求如下:
-
函数简短,通常3-5行;
-
函数内没有复杂的实现,比如:包含while、for 循环,递归等;
-
通常在多处有调用;
注意: inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。下图为《C++prime》第五版关于inline的建议:
二、为什么要使用内联函数
函数调用是有时间和空间开销的。程序在执行一个函数之前需要做一些准备工作,要将实参、局部变量、返回地址以及若干寄存器都压入栈中,然后才能执行函数体中的代码;函数体中的代码执行完毕后还要清理现场,将之前压入栈中的数据都出栈,才能接着执行函数调用位置以后的代码。
如果函数体代码比较多,需要较长的执行时间,那么函数调用机制占用的时间可以忽略;如果函数只有一两条语句,那么大部分的时间都会花费在函数调用机制上,这种时间开销就就不容忽视。
三、内联函数和宏定义的区别
是不是感觉内联函数跟宏有点相似,它们是有区别的:
- 内联函数和普通函数相比可以加快程序的运行速度,在编译的时候内联函数可以直接镶嵌到目标代码中,而宏只是一个不加任何检查的简单的替换。内联函数要做参数类型检查。宏不是函数,只是在编译预处理阶段将程序中的有关字符串替换成宏体。
- inline是嵌入代码,在调用函数的地方直接把代码写到这个地方,而不用中断调用。对于短小的代码来说,inline增加空间消耗,换时间效率,也就是我们常说的空间换时间。但是inline需要根据具体情况来选择是否需要使用。
内联函数使用场景选择
- 既然内联函数可以提高效率,是不是都可以使用内联函数呢?
答案是不可以的,原因是内联是以代码膨胀(复制)为代价,省去函数调用的开销,从而提高函数的执行效率。
比如,有一千行的普通函数运行十次时,仅仅代码量只有1000+10,而一千行的内联函数运行十次时,代码量为1000*10,可想而知会影响编译器的速度,
如果执行函数体内的代码的时间远远比函数调用开销大,那么使用内联函数效益会很小,这时候牺牲空间换时间就显得不值当了,当然不是你想使用inline关键字来修饰函数,编译器就会给你执行,一个好编译器会自动取消不合理的内联。
以下情况不宜使用内联:
- 如果函数体内的代码较长,使用内联会导致消耗较多空间。
- 如果函数体内出现循环,执行函数体内代码的开销要比调用函数开销大。