现在计算机的硬件设备的性能增长速度异常迅猛,使得越来越多的程序员开始不再关注代码的执行效率,不再花费心思去构想精妙的算法,优化自己的代码,导致设计的系统越来越庞大、越来越复杂,性能却越来越差,程序员自己也逐渐沦落为蓝领技术工人。一个经过简单编码培训的人就可以胜任程序员的工作吗?我认为不是这样的。一个合格的程序员,除熟练掌握多种编程语言外,创造力才是程序员生命的源泉。而创造力并非天生的,需要丰富的经验加勤奋的思考。本文并非想探讨程序员的成长,只是将此作为引子,希望各位同仁能关注自己编写代码并能为之自豪,并以一个简单的例子说明关注代码优化问题导致的巨大性能提升。即使机器再好,一个编写不良的代码,依然难以达到理想的性能。
今天测试人员向我抱怨,说我们提交的API代码性能比较差,解析一个90万笔业务的报文居然用了9个小时,这当然是不能接受的。我自己简单测试下,发现在我的T43/1.5G机器上,API的解析速度只能达到每秒30笔,直观觉得代码应存在性能问题。我仔细查阅了程序,没有发现明显的问题。到底是什么导致性能损失的呢?我逐步跟踪每步代码的执行,终于找到了问题所在,简单地讲此性能问题是频繁调用函数strlen()导致的。各位可能非常惊讶,我当时也很惊讶,但情况确实如此。90万笔业务的报文长度约50M,解析报文时我们调用了自己编写的底层代码StrStrExt()替换系统的strstr()以便支持的GB18030汉字,而性能正是StrStrExt()底层函数导致的。
先看看原始的StrStrExt()函数的代码:
// 查找含汉字串的位置
char* StrStrExt(LPCSTR sSearch,LPCSTR sFind)
{
if (IsEmptyStr(sSearch)) return NULL;
if (IsEmptyStr(sFind)) return (char*)sSearch;
ULONG nOffset =0;
ULONG nIndex =0;
ULONG nMaxLen = strlen(sSearch);
ULONG nLen = strlen(sFind);
while(nOffset < nMaxLen)
{
for(nIndex=0; nIndex<nLen; nIndex ++)
{
if(sSearch[nOffset + nIndex] != sFind[nIndex]) break;
}
if(nIndex == nLen) return (char*)(sSearch + nOffset);
int n = IsChineseChar(sSearch + nOffset);
if(n > 0)
{
// 汉字处理
nOffset += n;
}
else
{
nOffset++;
}
}
return NULL;
}
发现strlen()对大字符串可能导致性能问题后,我将该函数修改如下:
char* StrStrExt(LPCSTR sSearch,LPCSTR sFind)
{
if (IsEmptyStr(sSearch)) return NULL;
if (IsEmptyStr(sFind)) return (char*)sSearch;
ULONG nOffset =0;
ULONG nIndex =0;
// ULONG nMaxLen = strlen(sSearch);
ULONG nLen = strlen(sFind);
// while(nOffset < nMaxLen)
while(sSearch[nOffset] != 0)
{
for(nIndex=0; nIndex<nLen; nIndex ++)
{
if(sSearch[nOffset + nIndex] != sFind[nIndex]) break;
}
if(nIndex == nLen) return (char*)(sSearch + nOffset);
int n = IsChineseChar(sSearch + nOffset);
if(n > 0)
{
// 汉字处理
// nOffset += n;
for(int ii=0; ii<n; ii++)
{
++nOffset;
if(sSearch[nOffset] == 0) break;
}
}
else
{
nOffset++;
}
}
return NULL;
}
新函数与原函数的唯一差别是不再使用strlen()去获取串的结束位置,而是直接通过\0结束符判断串的结束位置。修改后的代码在我T43的机器上,解析速度提高到每秒3000笔的速度,是原代码的近100倍,达到了系统性能指标的要求。
这个问题提示我们,程序员应时刻关注代码的性能问题,对核心代码编写者更是如此。
posted on 2008-01-06 12:39
飞鹰 阅读(664)
评论(0) 编辑 收藏