一直以来,我都是认为内存的分配效率很低,所以才有jemalloc和tcmalloc的现世,也花了大量精力去研究他们。 但最近的一个发现却让我大跌眼镜。
最近,有个函数的性能一直困扰着我。实现了一个哈希类,循环100W次,每次循环插入256个预先生成的随机数作为关键字。在本机测试中,一直保持在100秒左右无法下降。
即使所有的内存都使用预先分配,也只能达到50秒。怀疑malloc , 再怀疑memset。使出浑身解数,也难以达到预期。最后,做了2个性能测试,却豁然开朗,如下:
const int LOOP_COUNTER = 1000000 ;
void test_malloc()
{
time_t begin = ::time(NULL) ;
const size_t size = 256 ;
for(int counter = 0 ; counter < LOOP_COUNTER ; ++counter)
{
void * buffer = ::malloc(size) ;
if(buffer != NULL)
{
::memset(buffer , 0 , size) ;
::free(buffer) ;
}
}
time_t end = ::time(NULL) ;
}
const int LOOP_COUNTER = 1000000 ;
const int GDATA_SIZE = 256 ;
void test_fun(const char * addr , size_t size)
{
}
void test_call()
{
time_t begin = ::time(NULL) ;
for(int counter = 0 ; counter < LOOP_COUNTER ; ++counter)
{
for(int idx = 0 ; idx < GDATA_SIZE ; ++idx)
{
test_fun(NULL , 0) ;
}
}
time_t end = ::time(NULL) ;
}
很难想象,上面2个测试项,一个结果是5秒,另外一个是6秒。如果将test_fun注释掉,那么是1秒。也就是test_fun的调用代价等于内存分配的代价。