字符串数组初始化0 与memset 0 效率的分析

时间:2022-09-09 14:45:56

转自http://hi.baidu.com/yangyangye2008/blog/item/cec4da0e3007c7366159f3c1.html

最近要分析程序的性能,所以上网查了查资料,的处理下面结论:

#defineARRAYSIZE 2048

voidmain() {

    chararrayA[ARRAYSIZE]={0};

    chararrayB[ARRAYSIZE];

    memset(array,0, ARRAYSIZE);

}

 

char arrayA[ARRAYSIZE] = {0};
编译是先arrayA[0]赋值为0, 再调用memset初始化其他的数组元素. 

char arrayA[ARRAYSIZE] = {0};
效率很难比用memset高,因为综上分析,我觉得给一块内存赋值的效率很难超越memset。

 

memset

语法:

#include <cstring>void*memset(void*buffer,intch,size_tcount);

memset()拷贝chbuffer的前count字符中,并返回buffer。memset()对于以某一值初始化一段内存非常有用。例如,这个命令:

constintARRAY_LENGTH=300; charthe_array[ARRAY_LENGTH];     // zero out the contents of the_array memset(the_array,'\0', ARRAY_LENGTH);

…是非常有效率的方法来设置the_array中的所有值为零。

下表比较了两种不同的方式来初始化字符数组:for循环和memeset()。随着初始化数据量的增加,memset()很清晰的做的更快:

耗时 for循环 memset
1000 0.016 0.017
10000 0.055 0.013
100000 0.443 0.029
1000000 4.337 0.291

 

如连接:

http://topic.csdn.net/u/20100208/10/e67ed254-9129-4afa-bec6-1559f114d803.html

 

 

变量的初始化

   要是极度追求速度的话,“定义变量并严格初始化”并不是一条黄金法则,如果流程上并不需要对变量初始化的话。

    这取决于你对“初始化”的概念是怎么理解的。如果你把初始化仅仅理解为变量定义时的初始化的话,那么“定义变量并严格初始化”有时就不是必要的了。例如下面的变量a在定义的时候就不需要对它初始化:

 int a = 0; // 这里的初始化是多余的,因为它的值从标准输入设备读取。
scanf("%d", &a);


   很多人就是把“变量的初始化”理解为“变量定义时的初始化”,从而坚持“定义变量并严格初始化”这条规则,这其实是不正确的这样做会带来多余的初始化,从而降低了效率。从上面看,楼主已经意识到了这个问题,而且正在着手处理。

    变量初始化的正确理解应该是“定义的变量第一次有一个给定的值(状态)”,无论这个值是通过变量定义时的初始化、定义后的赋值或者函数参数传递等方式得到。有这样的理解,那么“定义变量并严格初始化”一般情况下就是一条黄金法则(及其特殊的情况下定义变量只是为了使用它的类型特征,我们不考虑这种情况)。因为定义变量的最终目的就是使用变量(如果不使用它的话,也就不需要定义这个变量了),使用之前变量必须要从程序中得到一个给定值,这样的使用才是有意义的。

    这里的“变量”可以是一般变量、数组、结构体、类(C++)或者动态分配的内存空间。

 

 提出几条不算成熟的建议:

1:非必要情况不对内存使用memset清零,尤其是大块内存。

2:如某结构体或内存块在使用前会逐一赋值,则不需要对其进行memset初始化。

3:字符串的初始化可以对其第一个字节赋值0。

     使用strcpy拷贝的字符串不需要进行初始化。

     使用strncpy拷贝的字符串,建议不要先进行memset全部清零,而是在strncpy后,根据字符串实际长度,对字符串后一个字节置零。

     在做流程判断的时,尽量减少使用字符串比较,而采用整形或布尔量比较。

4:减少结构体转换和copy代码。对结构体尤其是包含长字符串的结构体复制时,建议慎用memcpy,而采取逐一赋值的方式。

5: 非必要不使用malloc和free,不但容易造成内存泄露,而且动态分配内存快时,系统的内存堆状况可能会影响分配效率(比如内存碎片很多时)。建议对一些动态分配的数组,采用定义一个足够大的数组方式.(这里有个问题:局部变量的最大尺寸是多少呢,也就是说进程栈空间是多少呢?这个应该是有限制的,但是每种操作系统或编译器的限制是多少呢,应该不能在栈空间里定义一个几十M或一个G大的数组吧?)

6:unix程序是基本上是以进程模式运行的,可以合理使用全局静态变量。减少分配内存的开销。在多线程程序里慎用全局变量

我觉得在写代码的时候,不但要把功能实现,该精益求精还是尽量注意,也许确实项目组里开发的时候对代码质量细节控制不是很严格吧。