在编程时,为了节省空间,我们经常会调用malloc函数来动态申请空间。但是,却不知道,正是因为这一点点的吝啬心,让我们的程序运行效率出奇的低。
那么,引起效率低下的原因是什么呢,接下来,让我们探索探索。
探索一、
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#define M 100
#define N 100
void TestMain(int n,int flag);
int _tmain(int argc, _TCHAR* argv[])
{
clock_t start, end;
start = clock();
TestMain(10000000,1);
end = clock();
printf("The time was: %f\n", (double)(end - start) / CLK_TCK);
start = clock();
TestMain(10000000,2);
end = clock();
printf("The time was: %f\n", (double)(end - start) / CLK_TCK);
return 0;
}
void MallocTest()
{
int **dis = NULL;
int i,j;
dis = (int **)malloc((N + 1) * sizeof(int *));
for (int i = 0; i <= N; ++i)
{
dis[i] = (int *)malloc((M + 1) * sizeof(int));
}
for (i = 1; i <= N; i++)
{
for (j = 1; j <= M; j++)
{
dis[i][j] = 1;
}
}
for (int i = 0; i <= N; ++i)
{
free(dis[i]);
}
free(dis);
}
void ArryTest()
{
int dis[N + 1][M + 1];
int i,j;
for (i = 1; i <= N; i++)
{
for (j = 1; j <= M; j++)
{
dis[i][j] = 1;
}
}
}
void TestMain(int n,int flag)
{
if (flag == 1)
{
for (int i = 0; i < n; i++)
{
MallocTest();
//ArryTest();
}
}
else
{
for (int i = 0; i < n; i++)
{
//MallocTest();
ArryTest();
}
}
}
运行结果:
从上面我们可以看到,MallocTest和ArryTest都申请了同样大小的空间,并且进行了同样的操作。在将它们同样执行一千万次以后,所用的时间:MallocTest为564.631s,ArryTest为232.96s,很明显,因为malloc的使用,导致程序效率降低了一倍还多。
探索一中考虑的是二维数组的情况,有人可能会说,二维数组操作多了很多次循环,这多的操作步骤引起了程序效率的低下,那么,当我们将维数降到一维的时候,情况又会怎样呢?
探索二、
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#define M 100
#define N 100
void TestMain(int n,int flag);
int _tmain(int argc, _TCHAR* argv[])
{
clock_t start, end;
start = clock();
TestMain(100000000,1);
end = clock();
printf("The time was: %f\n", (double)(end - start) / CLK_TCK);
start = clock();
TestMain(100000000,2);
end = clock();
printf("The time was: %f\n", (double)(end - start) / CLK_TCK);
return 0;
}
void MallocTest()
{
int *dis = NULL;
int i,j;
dis = (int *)malloc((N + 1) * sizeof(int *));
for (int i = 0; i <= N; ++i)
{
dis[i] = 1;
}
free(dis);
}
void ArryTest()
{
int dis[N + 1];
int i,j;
for (i = 1; i <= N; i++)
{
dis[i] = 1;
}
}
void TestMain(int n,int flag)
{
if (flag == 1)
{
for (int i = 0; i < n; i++)
{
MallocTest();
//ArryTest();
}
}
else
{
for (int i = 0; i < n; i++)
{
//MallocTest();
ArryTest();
}
}
}
运行结果:
这是在一维的情况下对它们的测试结果,其中MallocTest和ArryTest均执行了一亿次。很明显,这次的差距也有两倍多。。。
那么,单变量的情况下,又会是什么样的结果呢?
探索三、
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#define M 100
#define N 100
void TestMain(int n,int flag);
int _tmain(int argc, _TCHAR* argv[])
{
clock_t start, end;
start = clock();
TestMain(100000000,1);
end = clock();
printf("The time was: %f\n", (double)(end - start) / CLK_TCK);
start = clock();
TestMain(100000000,2);
end = clock();
printf("The time was: %f\n", (double)(end - start) / CLK_TCK);
return 0;
}
void MallocTest()
{
int *dis = NULL;
dis = (int *)malloc(sizeof(int));
*dis = 1;
free(dis);
}
void ArryTest()
{
int dis;
dis = 1;
}
void TestMain(int n,int flag)
{
if (flag == 1)
{
for (int i = 0; i < n; i++)
{
MallocTest();
}
}
else
{
for (int i = 0; i < n; i++)
{
ArryTest();
}
}
}
运行结果:
同样上述两个函数分别调用了一亿次,结果差了好几十倍呢。。
从以上几个测试中,我们可以得出以下结论:
1、动态申请内存空间会影响程序效率;
2、当动态申请的空间越小时,对效率的影响越大。
那么,为什么会有这种差异呢?让我们看看动态申请内存空间和采用临时变量两种情况的汇编代码吧。
int *dis = NULL;上面这段代码的汇编代码为:
dis = (int *)malloc(sizeof(int));
*dis = 1;
free(dis);
int *dis = NULL;
012413AE mov dword ptr [dis],0
dis = (int *)malloc(sizeof(int));
012413B5 mov esi,esp
012413B7 push 4
012413B9 call dword ptr [__imp__malloc (12482B4h)]
012413BF add esp,4
012413C2 cmp esi,esp
012413C4 call @ILT+310(__RTC_CheckEsp) (124113Bh)
012413C9 mov dword ptr [dis],eax
*dis = 1;
012413CC mov eax,dword ptr [dis]
012413CF mov dword ptr [eax],1
free(dis);
012413D5 mov esi,esp
012413D7 mov eax,dword ptr [dis]
012413DA push eax
012413DB call dword ptr [__imp__free (12482B8h)]
012413E1 add esp,4
012413E4 cmp esi,esp
012413E6 call @ILT+310(__RTC_CheckEsp) (124113Bh)
而,下面的临时变量的代码为:
int dis2;
dis2 = 1;
它的汇编代码为:
int dis2;
dis2 = 1;
012413EB mov dword ptr [dis2],1
从汇编代码我们可以看出,使用malloc动态申请内存空间比采用临时变量需要更多的汇编代码。多出这么多汇编代码,机器代码多出多少,大家应该都能猜个大概吧。
综上,给出以下建议:
当对内存空间消耗不是很大时,我们应该尽量使用临时变量,这样可以提高代码效率。当然,如果你的程序对内存大小要求相当严格,那就另当别论了。