C/C++小型对象分配的性能测试笔记

来源:互联网 发布:永中office 知乎 编辑:程序博客网 时间:2024/06/07 14:58

 

实际上new和delete内部使用的就是free和malloc,而在C中free的参数是void*,malloc返回的是void*。而C++添加了额外的行为就是,malloc之后自动调用够着函数,free之前调用析构函数。所以上面A没有成员数据,而B有,在delete时没有出现错误,原因就在于,在delete pb时,调用B的析构函数,这里没有问题,然后将pb交给free。这就回到了原始的C中,所以整个过程就没有问题。

 

缺省的Free Store分配器

在C++的缺省内存分配器的性能不好,一个原因是他仅仅是对Cheap分配器的浅层包装(对malloc,realloc,free的包装)。

针对于内置类型(没有构造函数的消耗),实际上C++的new和使用C中的malloc是没有差别的。(C++的new内部仍然使用malloc)。

缺省内存分配器的性能不好,问题出在:

free的参数是void*,malloc返回的是void*,那么编译器在释放内存的时候必然要知道这个内存块得大小,然后再做实际的内存管理操作。那么他就会对分配的内存块登记一些信息,因此登记信息的内存消耗是要考虑的。特别是在分配小型对象的时候。

下面是一个测试:使用mingw32-make, g++编译器

clock_t tm = clock();

char *arr[1024*100];

//6: FixedAllocator fa(1);

//3: arr[0] = (char*)malloc(sizeof(char)*1024*100);

//4: arr[0] = new char[1024*100];

for(int i=0; i<1024*100; ++i)

{

        //1: arr[i] = new char;

//2: arr[i] = (char*)malloc(sizeof(char));

//5: arr[i] = func(sizeof(char));//char* func(int){}

//6: arr[i] = (char*)fa.Allocate();

}

cout<<"cost "<<(clock()-tm)*0.001f<<endl;

 

1:使用new的结果:

time         mem

0.022s       2300K

0.02s        2300k

2: 使用malloc的结果

0.03s        2300k

0.007s       2300k

0.01s        2300k

3:一次使用malloc的结果

0s           612k

0s           612k

4:一次使用new的结果

0s           612k

5:在for中调用一个以int为参数的函数

0s           600k

0s           600k

6: 使用Loki中的FixedAllocator,即使用小型分配管理

0.015s       812k

0.015s       812k

 

从上面的数据可以看出,使用new和malloc针对于内置类型是一致的。而如果我们一次分配这么多的内存和分次分配这么多的内存,的差距是很明显的,可以推出:针对于小型对象使用内置的内存分配在内存上面有额外的开销,可以计算出来大概有16bytes左右。在时间上的开销也是很明显的。 

使用小型对象的管理,能够解决对小型对象在内存上的额外消耗。在时间上有一定的改善。

PS: Loki是C++设计新思维书中实现的一个库,针对小型对象的分配使用SmallObj.h,这种实现方法在STL3.2.3中的stl_alloc.h的内存管理也有类似的实现