現在計算機的硬件設備的性能增長速度異常迅猛,使得越來越多的程序員開始不再關注代碼的執行效率,不再花費心思去構想精妙的算法,優化自己的代碼,導致設計的系統越來越龐大、越來越復雜,性能卻越來越差,程序員自己也逐漸淪落為藍領技術工人。一個經過簡單編碼培訓的人就可以勝任程序員的工作嗎?我認為不是這樣的。一個合格的程序員,除熟練掌握多種編程語言外,創造力才是程序員生命的源泉。而創造力并非天生的,需要豐富的經驗加勤奮的思考。本文并非想探討程序員的成長,只是將此作為引子,希望各位同仁能關注自己編寫代碼并能為之自豪,并以一個簡單的例子說明關注代碼優化問題導致的巨大性能提升。即使機器再好,一個編寫不良的代碼,依然難以達到理想的性能。
今天測試人員向我抱怨,說我們提交的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
飛鷹 閱讀(668)
評論(0) 編輯 收藏