【响应时间瓶颈】
网络响应不及时的原因有很多,我们现在说的是server端的响应速度。
具体的说,完成同样的任务,a程序要1s,b要10s。
造成这种性能下降的原因有,阻塞操作(IO,加锁),程序效率(本来可以用10条指令完成的工作,现在扩展到100条)。
我们谈下程序效率。低效率的程序,不仅会使响应时间拉长,还会使CPU占有率提高。
1 复杂度高的算法。
曾经写出过 n的3次方的代码。可想而之,哪怕数据量到1000,响应时间也要长到不能接受。
2 不合理的语言特性---动态分配内存
使用new malloc频繁的分配内存。
char* t_pBuf = new char[512*1024]; 这样一个操作,单步执行的时候,可能不到1ms。
但是如果累计执行一万次,可以看到他的执行时间是“alloc cost 10062ms”
如果程序需要支持的规模达到这种程度,也就是说,1个请求,可能会言辞10s才会得到响应。
这是程序中通常见到的程序规模引起的瓶颈问题。
你的程序计算支持多少的任务量。这些任务量会引起某个模块多少次使用量。这么大的使用量,是否会导致执行效率降低到不能接受??
为什么new操作会有这么大的CPU开销呢?因为,操作系统在做内存管理的时候涉及到大量的查找开销,如果内存不足,可能引起“颠簸”,需要移动内存腾出更大的空间,则可能造成更大的影响。 尤其是分配大块内存的操作,一定要谨慎。
而在栈上操作,基本没有什么消耗!
只要是在内存中的操作,在算法复杂度控制在o(n)以内,数据量不大的情况下,一般不会引起大的性能问题。
3 未完待续
-----------------------------
附代码段
LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
DWORD t_nMS = ::GetTickCount();
for ( int i = 0; i<10000; i++)
{
char t_pBuf[512*1024];
memset(t_pBuf, 0, 512*1024);
}
DWORD t_nT = ::GetTickCount() - t_nMS;
FILE * fp = fopen("D://b.txt", "w");
ATLASSERT(fp != NULL);
fprintf(fp, "stack with memset cost %dms", t_nT);
fclose(fp);
return 0;
}
LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// TODO: Add validation code
//CloseDialog(wID);
DWORD t_nMS = ::GetTickCount();
for ( int i = 0; i<10000; i++)
{
char* t_pBuf = new char[512*1024];
delete t_pBuf;
}
DWORD t_nT = ::GetTickCount() - t_nMS;
DWORD t_nMS2 = ::GetTickCount();
for ( int j = 0; j<10000; j++)
{
char* t_pBuf = new char[512*1024];
memset(t_pBuf, 0, 512*1024);
delete t_pBuf;
}
DWORD t_nT2 = ::GetTickCount() - t_nMS2;
FILE * fp = fopen("D://a.txt", "w");
ATLASSERT(fp != NULL);
fprintf(fp, "alloc cost %dms, alloc with memset cost%dms", t_nT, t_nT2);
fclose(fp);
return 0;
}
-------
结果
alloc cost 10062ms, alloc with memset cost13328ms
stack with memset cost 3188ms