代码运行效率及程序大小分析一例

来源:互联网 发布:数据可视化概念 编辑:程序博客网 时间:2024/05/22 14:21
  之前一直看到有经验的程序员说,代码写得太低劣了,许多变量都定义成全局的,当时的理解大致是这样程序的健壮性不好,不利于移植、修改和维护,牵一发而动全身。今天在测试一个代码运行效率的程序时,做了一个测试程序,让我对这个问题有了新的认识。这个程序要说明的问题是,尽可能在循环的时候只运行本层的数据,单层的循环有利于节省CPU的运行时间。

  测试代码如下:

#include<stdio.h>

#include<windows.h>

int data1[10000000] = 01;

int data2[10000000] = 01;

void loop_layer_test();

 

int main()

{

loop_layer_test();

return 0;

}

void loop_layer_test()

{

int m = GetTickCount();

int outer = 0;

int inner = 0;

for(outer = 0; outer < 10000000; outer ++)

{

data1[outer] = outer;

data2[outer] = outer;

}

printf("%d\n", GetTickCount() - m);

m = GetTickCount();;

for(inner = 0; inner < 10000000; inner ++)

{

data1[inner] = inner;

}

for(outer = 0; outer < 10000000; outer ++)

{

data2[outer] = outer;

}

printf("%d\n", GetTickCount() - m);

}

 

程序运行的结果为:9462 

 

   这说明在循环中要进行相关的遍历、赋值操作,如果不是必须的话,最好可以做到只运行单层数据,如果数据量特别大的话,会节约大量CPU的时间。

   到这里本来对这段代码的分析已经结束了,可是无意中,我将鼠标放到了这个程序所在的文件夹,171M,这个程序所在的文件夹竟然171M !这让我感到很震惊!我再看看生成exe文件,92M !不到100行的代码,没有嵌入任何资源,生成的程序达到了92M,这是让人不能忍受的。

   作为一个菜鸟,面对这样的问题,总是无法理解的。我再去认真分析这个程序,数据,还是这个数据太多了,让程序体积如此庞大。问题出现在

int data1[10000000] = 01;

int data2[10000000] = 01;

这两条语句,这样定义了2个数组并进行了初始化,消耗了大量的内存,在全局变量区生成了大量的数据,导致程序体积如此庞大。要解决这个问题,我想到的方法是将数据放到loop_layer_test函数中,这样在调用完loop_layer_tes函数后,会释放掉这些生成的大量数据,程序的体积自然也就下来了。

   按照这样的思路,我将

int data1[10000000] = 01;

int data2[10000000] = 01;

放入了loop_layer_test函数中,编译时没有问题,运行时发生如下错误:


   我忽略了一个基本事实,栈中数据量是不能超过2M的,这么多的数据放入函数中,会导致栈溢出。

   既然在栈中不能储存这90M的数据,那就开辟一块堆内存吧,在堆中对数据大小原则上是没有限制的。于是,将以上数组的定义和赋值改为动态分配:

int *data1 = (int*)malloc(sizeof(int[10000000]));

int *data2 = (int*)malloc(sizeof(int[10000000]));

程序的其他部分不需要作任何修改,只需在结尾加上:

free(data1);

free(data2);

语句,释放掉申请的内存。至此,对程序的改造算是完成了。编译运行都没有问题,再去看看生成了exe文件,只有168k。这才是一个正常的程序。

  后来我在看之前写的那个全局变量的代码,发现在全局变量区只是声明而不不为数组分配内存,也就是将代码改成如下形式:

int data1[10000000] ;

int data2[10000000] ;

也是可以大大缩小程序体积的,这样程序也只有100k

   通过这个demo,总结以下几点:

(1)尽可能在循环的时候只运行本层的数据,单层的循环有利于节省CPU的运行时间;

(2)如果不是必须的话,尽可能少使用全局变量。如果要定义全局变量,也最好不要分配内存;

(3)程序的大小是在main函数return那一刻敲定的,return时内存中有多少数据将直接决定程序的大小;

(4)栈中不能放大量数据,会产生栈溢出异常。

PS:第一次写技术类文章,叙述难免含糊。本人菜鸟一个,如理解有误,欢迎指正!

 

原创粉丝点击