C++笔记 内联函数
内联函数作用:
通过替换函数来提升性能。针对一些代码量较少,但是需要重复使用的场景。
底层实现原理剖析:
源代码:
__forceinline int Add(int a, int b)
{
return a + b;
}
int main()
{
int num1 = 1;
int num2 = 2;
int myNum = Add(num1, num2);
}
// 优化过后的底层汇编代码
int main()
{
/*
00F41F50 push ebp
00F41F51 mov ebp,esp
00F41F53 sub esp,0E4h
00F41F59 push ebx
00F41F5A push esi
00F41F5B push edi
00F41F5C lea edi,[ebp-0E4h]
00F41F62 mov ecx,39h
00F41F67 mov eax,0CCCCCCCCh
00F41F6C rep stos dword ptr es:[edi]
00F41F6E mov ecx,offset _5BD3FBCE_consoleapplication2.cpp (0F57008h)
00F41F73 call @__CheckForDebuggerJustMyCode@4 (0F4142Eh)
int num1 = 1;
00F41F78 mov dword ptr [num1],1
int num2 = 2;
00F41F7F mov dword ptr [num2],2
int myNum = Add(num1, num2);
00F41F86 mov eax,dword ptr [num1]
00F41F89 add eax,dword ptr [num2] 直接进行 add 加法运算
00F41F8C mov dword ptr [myNum],eax
}
*/
// 未优化添加inline的底层代码
int main()
{
/*
int main()
{
01232530 push ebp
01232531 mov ebp,esp
01232533 sub esp,0E4h
01232539 push ebx
0123253A push esi
0123253B push edi
0123253C lea edi,[ebp-0E4h]
01232542 mov ecx,39h
01232547 mov eax,0CCCCCCCCh
0123254C rep stos dword ptr es:[edi]
0123254E mov ecx,offset _5BD3FBCE_consoleapplication2.cpp (01247008h)
01232553 call @__CheckForDebuggerJustMyCode@4 (0123142Eh)
int num1 = 1;
01232558 mov dword ptr [num1],1
int num2 = 2;
0123255F mov dword ptr [num2],2
int myNum = Add(num1, num2);
01232566 mov eax,dword ptr [num2]
01232569 push eax
0123256A mov ecx,dword ptr [num1]
0123256D push ecx
0123256E call Add (01231726h) 需要调用call 需要进行跳转 jump 函数表等操作
01232573 add esp,8
01232576 mov dword ptr [myNum],eax
}
*/
说明:从其他博主那复制的汇编结果本人测试一直无法触发内联函数。
内联函数触发规则 (只针对微软编译器进行总结):
- 递归函数。
- 在翻译单元中的其他位置通过指针引用的函数。
内联函数使用方法:
__forceinline
//强烈推荐编译器使用内联函数
inline
//普通内联函数方法
内联函数缺点:
容易造成代码膨胀,在替换的过程中会导致有大量的重复代码。整个文件体积变大从而影响性能。微软官方解释:“ 或是在某些情况下,甚至会损失性能(例如,由于较大可执行文件的分页会增加)。”
内联函数注意事项:
内联函数本身是一种建议,是开发者给编译器的在编译过程中提供的一种建议。至于是否选择使用内联函数这种方法本质上是取决于编译器。不同的编译器内联函数的替换规则是不一样的。所以一款好的编译器在底层的处理上不需要太多的关注。甚至不同的优化策略下内联函数可能都会不一样。尽量少使用__forceinline。