C++编程思想——内联

来源:互联网 发布:js捕获事件target 编辑:程序博客网 时间:2024/06/08 14:15

内联

内联方法以关键字:inline来标志,其实我们也常常的看到内联的函数,比如在类头文件中定义方法。内联方法的调用与普通方法没有什么不同,但是其性能之间的差别非常的大。

下面我们从不同的角度来认识这个内联。

1)首先了解普通函数的调用过程:

将函数的参数入栈,栈指针指向第一个参数;

指令地址入栈,指令指针指向第一条指令;

此时在堆栈中将保存方法的栈指针、自变量指针及帧指针,这些都用来反应当前函数的上下文环境。

注:栈指针,跟踪堆栈的使用情况;指令指针,存放下一条执行指令的地址;而还有链接寄存器(LR)是存放指令指针的地址;帧指针以标识堆栈中两个区域的边界,一个区域含有记录方法中状态的寄存器,另一个区域是调用方法的自变量分配的内存)

函数返回过程:

将返回值存储到寄存器中;

将方法调用过程中保存的寄存器进行清理工作;

将帧指针寄存器以及自变量指针寄存器从堆栈中回复到其相应的位置;

修改栈指针寄存器使其指向方法的第一个参数压栈前的位置;

从堆栈中找到返回地址将其存入指令指针中,并返回到调用者调用的位置。

 

从上述过程中,我们看到一个普通的函数调用将需要很多的寄存器,指令,消耗的时钟周期增加;如果方法是返回一个对象时,将对象复制到调用方法为返回值留存的存储空间也是一个开销;还有的就是可能不能对跨越方法边界的代码进行优化。

 

2)使用内联调用函数的过程:

将内联方法的连续代码快复制到调用方法的调用点处;为变量分配内存;将内联方法的输入参数和返回值映射到调用方法的局部变量空间内。因此说内联是对运行时间进行的优化。适用情况1.函数较为的简单;2.一个函数不断的被重复调用。内联其实是以空间来换取时间。

 

3)避免内联

并不是任何时候都应该使用内联,当1.函数体内的代码较长时,因为内联会在调用出对代码进行展开;2.函数体内出现了循环。这两种情况下的内联会造成的代码的膨胀,尽管现在内存容量发展的很快,但是缓存问题和页面错误问题还是不能避免,当现有的缓存无法容纳所有需要的工作页面集合,命中率降低,频繁产生页面错误。 另外,滥用的内联程序尽管会执行较少的指令,但是会消耗较多的时间。

 

宏不是函数,它只是简单的替换,不会进行类型检查。预处理器复制宏代码代替函数调用,因此参数压栈,汇编语言的调用,等过程。而内联是在编译阶段插入代码。

 

0 0