内联函数真的可以提高程序执行效率吗
Posted kongslly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内联函数真的可以提高程序执行效率吗相关的知识,希望对你有一定的参考价值。
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">内联函数</span>
定义:
内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数,又称为内嵌函数。
内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。
真实的函数调用过程如下所示,函数调用的工作都是与完成特定任务操作无关的额外开销。
规则:
1.对函数的内联声明必须在调用之前,因为内联函数的代码在程序运行时是直接嵌在调用处的,它不影响链接,只在编译时确定运行代码。因此编译时,在调用之前看到内联声明就十分必要。
2.内联函数应该尽可能的小,且要结构简单,这样嵌入的代码才不会影响调用函数的主体结构。
(1)、内联函数之后不要含义复杂的结构控制语句,如switch while,如果含有这些则编译的时候就会无视内联声明,直接当作普通函数处理。
(2)、内联函数适用于1-5行的小函数。
(3)、递归函数属于结构复杂的函数不能作为内联函数处理。
内联函数一般适用场合:
1.函数体适当小,这样就使嵌入工作容易进行工作,不会破坏原调用主体。
2.程序中特别是在循环中反复执行该函数,这样就使嵌入的效率相对高。
3.程序并不多出出现该函数调用,这样就使嵌入工作量相对较少,代码也不会剧增。
实例:
一个小例子,分别使用普通函数调用、内联函数和宏,观察三者运行的不同情况
Windows下运行(VS2013):
#include "stdafx.h" #include <iostream> #include <time.h> using namespace std; int calc1(int a, int b) returna + b; inline int calc2(int a, int b) returna + b; #define CALCE(a,b) a + b int _tmain(int argc, _TCHAR* argv[]) int x[1000] = 0; int y[1000] = 0 ; int z[1000] = 0 ; cout<<"使用普通函数测试开始"<<endl; clock_t t = clock(); for (int i = 0; i< 1000; ++i) //代码无意义只是测试使用 for (int j = 0; j< 1000; ++j) for (int k = 0; k< 1000; ++k) z[i] = calc1(x[j], y[k]); cout<<"使用普通函数用时:"<< (clock() - t) / CLK_TCK<<"秒"<<endl; cout<<"使用内联函数测试开始"<<endl; t = clock(); for (int i = 0; i< 1000; ++i) //代码无意义只是测试使用 for (int j = 0; j< 1000; ++j) for (int k = 0; k< 1000; ++k) z[i] = calc2(x[j], y[k]); cout<<"使用内联函数用时:"<< (clock() - t) / CLK_TCK<<"秒"<<endl; cout<<"使用宏测试开始"<<endl; t = clock(); for (i nti = 0; i< 1000; ++i) //代码无意义只是测试使用 for (int j = 0; j< 1000; ++j) for (int k = 0; k< 1000; ++k) z[i] = CALCE(x[j], y[k]); cout<<"使用宏用时:"<< (clock() - t) / CLK_TCK<<"秒"<<endl; system("pause"); return 0;
运行结果好像内联函数并不尽人意,将代码反汇编发现,只有宏定义真正实现了内嵌,内联函数还行继续调用,不知道什么原因。
//宏定义: z[i] = CALCE(x[j], y[k]); 0016929F moveax,dwordptr [ebp-2F64h] 001692A5 movecx,dwordptr x[eax*4] 001692AC movedx,dwordptr [ebp-2F70h] 001692B2 addecx,dwordptr y[edx*4] 001692B9 moveax,dwordptr [ebp-2F58h] 001692BF movdwordptr z[eax*4],ecx //内联函数: z[i] = calc2(x[j], y[k]); 0016914B moveax,dwordptr [ebp-2F4Ch] 00169151 movecx,dwordptr y[eax*4] 00169158 pushecx 00169159 movedx,dwordptr [ebp-2F40h] 0016915F moveax,dwordptr x[edx*4] 00169166 pusheax 00169167 call calc2 (0161028h) 0016916C add esp,8 0016916F movecx,dwordptr [ebp-2F34h] 00169175 movdwordptr z[ecx*4],eax //普通函数: z[i] = calc1(x[j], y[k]); 00168FF3 moveax,dwordptr [ebp-2F28h] 00168FF9 movecx,dwordptr y[eax*4] 00169000 pushecx 00169001 movedx,dwordptr [ebp-2F1Ch] 00169007 moveax,dwordptr x[edx*4] 0016900E pusheax 0016900F call calc1 (0161352h) 00169014 add esp,8 00169017 movecx,dwordptr [ebp-2F10h] 0016901D movdwordptr z[ecx*4],eax
好像内联函数与普通函数的反汇编执行过程是一样的没啥区别,只有宏定义的是真正嵌入到程序中了。
Linux下运行效果(centos 7 g++4.8.2): #include <iostream> #include <time.h> using namespace std; int calc1(int a, int b) return a + b; inline int calc2(int a, int b) return a + b; #define CALCE(a,b) a + b int main(int argc, char* argv[]) int x[10000] = 0; int y[10000] = 0 ; int z[10000] = 0 ; cout<< "使用普通函数测试开始" <<endl; time_t t = time(NULL); for (inti = 0; i< 10000; ++i) //代码无意义只是测试使用 for (int j = 0; j < 1000; ++j) for (int k = 0; k < 1000; ++k) calc1(x[j], y[k]); cout<< "使用普通函数用时:" << (time(NULL) - t) << "秒" <<endl; cout<< "使用内联函数测试开始" <<endl; t = time(NULL); for (int i = 0; i< 10000; ++i) //代码无意义只是测试使用 for (int j = 0; j < 1000; ++j) for (int k = 0; k < 1000; ++k) calc2(x[j], y[k]); cout<< "使用内联函数用时:" << (time(NULL) - t) << "秒" <<endl; cout<< "使用宏测试开始" <<endl; t = time(NULL); for (int i = 0; i< 10000; ++i) //代码无意义只是测试使用 for (int j = 0; j < 1000; ++j) for (int k = 0; k < 1000; ++k) CALCE(x[j], y[k]); cout<< "使用宏用时:" << (time(NULL) - t) << "秒" <<endl; //system("pause"); return 0;
运行结果好像也是不怎么样:
使用关键字强制内联:
inlineint calc2(int a, int b)__attribute__((always_inline));
这个语句可以去查查,好像很有用。#include <iostream> #include <time.h> using namespace std; int calc1(int a, int b) return a + b; inlineint calc2(int a, int b) __attribute__((always_inline)); inlineint calc2(int a, int b) return a + b; #define CALCE(a,b) a + b int main(intargc, char* argv[]) int x[10000] = 0; int y[10000] = 0 ; int z[10000] = 0 ; cout<< "使用普通函数测试开始" <<endl; time_t t = time(NULL); for (inti = 0; i< 10000; ++i) //代码无意义只是测试使用 for (int j = 0; j < 1000; ++j) for (int k = 0; k < 1000; ++k) calc1(x[j], y[k]); cout<< "使用普通函数用时:" << (time(NULL) - t) << "秒" <<endl; cout<< "使用内联函数测试开始" <<endl; t = time(NULL); for (inti = 0; i< 10000; ++i) //代码无意义只是测试使用 for (int j = 0; j < 1000; ++j) for (int k = 0; k < 1000; ++k) calc2(x[j], y[k]); cout<< "使用内联函数用时:" << (time(NULL) - t) << "秒" <<endl; cout<< "使用宏测试开始" <<endl; t = time(NULL); for (inti = 0; i< 10000; ++i) //代码无意义只是测试使用 for (int j = 0; j < 1000; ++j) for (int k = 0; k < 1000; ++k) CALCE(x[j], y[k]); cout<< "使用宏用时:" << (time(NULL) - t) << "秒" <<endl; //system("pause"); return 0;
运行效果好像也不过如此,但是好像内联起到了一些作用:
具体的反汇编就不看了,因为Linux下的反汇编实在是看不懂。但是内联作用不大是为神马???和书上讲的不一样呢???
以上是关于内联函数真的可以提高程序执行效率吗的主要内容,如果未能解决你的问题,请参考以下文章