内联函数真的可以提高程序执行效率吗
来源:互联网 发布:刷生死狙击金币软件 编辑:程序博客网 时间:2024/06/12 01:33
<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 + bint _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 pushecx00169159 movedx,dwordptr [ebp-2F40h] 0016915F moveax,dwordptr x[edx*4] 00169166 pusheax00169167 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 pushecx00169001 movedx,dwordptr [ebp-2F1Ch] 00169007 moveax,dwordptr x[edx*4] 0016900E pusheax0016900F 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 + bint 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 + bint 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下的反汇编实在是看不懂。但是内联作用不大是为神马???和书上讲的不一样呢???
- 内联函数真的可以提高程序执行效率吗
- 内联函数--提高C/C++程序执行效率
- select()函数分析 (可以提高程序的效率)
- 如何提高程序的执行效率
- 提高javascript函数的执行效率
- SQL语句书可以提高执行效率的方法
- 有哪几种途径可以提高C#应用程序的执行效率
- 测内联函数的效率
- 提高程序的效率
- 30个提高Web程序执行效率的好经验
- 30个提高Web程序执行效率的好经验
- 30个提高Web程序执行效率的好经验
- 30个提高Web程序执行效率的好经验
- 30个提高Web程序执行效率的好经验
- 30个提高Web程序执行效率的好经验
- 30个提高Web程序执行效率的好经验
- 为何多线程就能提高Java程序的执行效率
- 30个提高Web程序执行效率的好经验
- java.sql.SQLException: QueryRunner requires a DataSource to be invoked in this way, or a Connection
- Java实现B树
- 领导符合这9条标准,就值得追随!(必看)
- Android 中文API:Running Gradle Builds
- 下载图片webcollector
- 内联函数真的可以提高程序执行效率吗
- 贪心阶乘之和
- PHP中yii2日期时间控件的使用
- POJ 2109 Power of Cryptography
- 在ECSHOP首页显示各等级会员价格的方法 列表页面显示会员等级价格
- Commit
- UITableView 02
- css全局代码
- Android SystemProperty