内联函数真的可以提高程序执行效率吗

<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下的反汇编实在是看不懂。但是内联作用不大是为神马???和书上讲的不一样呢???




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值