这两天在对一个服务器做压力测试时,CPU使用率一直很高,保持在170%(双核)左右,很不可思议。因为程序的逻辑是非常简单的。定位半天终于发现罪魁祸首竟然在调用memset()上。注释掉所有的memset,CPU使用率一下就降到10%一下。令人非常惊讶。
对于memset的使用,基于“定义变量并严格初始化”这条黄金法则。所以,每次使用一块内存时都很小心的初始化它,以防止某些意外错误的发生。但却不知道memset()初始化大块内存时,耗费吓人!其实我们只要流程上控制好,根据需要采取首位或所需最后位补0的方法,也是可以搞定这个事情的。
具体可以见下面这段测试程序:
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#define BUF_LEN (1024*1024)
#define TIMES 512
double use_noset()
{
timeval timestart,timeend;
gettimeofday(×tart, NULL);
for( int i = 0; i < TIMES; i ++)
{
char* buff = new char[BUF_LEN];
for(int j = 0; j < BUF_LEN; j++)
{
buff[j] =0;
}
delete[] buff;
}
gettimeofday(&timeend, NULL);
double linStart = 0,linEnd = 0;
linStart = ((double)timestart.tv_sec * 1000000 + (double)timestart.tv_usec); //unit S
linEnd = ((double)timeend.tv_sec * 1000000 + (double)timeend.tv_usec); //unit S
double time = linEnd-linStart;
return time;
}
double use_memset()
{
timeval timestart,timeend;
gettimeofday(×tart, NULL);
for( int i = 0; i < TIMES; i ++)
{
char* buff = new char[BUF_LEN];
memset(buff,0,BUF_LEN);
delete[] buff;
}
gettimeofday(&timeend, NULL);
double linStart = 0,linEnd = 0;
linStart = ((double)timestart.tv_sec * 1000000 + (double)timestart.tv_usec); //unit S
linEnd = ((double)timeend.tv_sec * 1000000 + (double)timeend.tv_usec); //unit S
double time = linEnd-linStart;
return time;
}
double use_setlast()
{
timeval timestart,timeend;
gettimeofday(×tart, NULL);
for( int i = 0; i < TIMES; i ++)
{
char* buff = new char[BUF_LEN];
buff[BUF_LEN-1] = ‘\0′;
delete[] buff;
}
gettimeofday(&timeend, NULL);
double linStart = 0,linEnd = 0;
linStart = ((double)timestart.tv_sec * 1000000 + (double)timestart.tv_usec); //unit S
linEnd = ((double)timeend.tv_sec * 1000000 + (double)timeend.tv_usec); //unit S
double time = linEnd-linStart;
return time;
}
int main(int argc, char** argv)
{
double t1 = use_noset();
double t2 = use_memset();
double t3 = use_setlast();
printf(”no memset used =%f, memset used t2= %f, no memset used t3=%f,t1/t2=%f t2/t3=%f\n”, t1, t2, t3,(t1/t2), (t2/t3));
}
跑出来的结果是:
no memset used =2118321.000000, memset used t2= 102161.000000, no memset used t3=37.000000,t1/t2=20.735124 t2/t3=2761.108108
从结果可以看出,memset(),比直接给每个字节赋值要快20倍,但跟后位置零相比,整整慢了近3k倍。如果运行高并发的程序这种效率就很要人命。
教条主义真是害人。多动手实践,不要做多余的事情,控制好你的程序才是最关键的。
No Comments Now!
Be the first to comment on this entry.