做者:馮老師,華清遠見教育集團講師。程序員
在面試題中常常考到各類各類的字符串處理函數,下面就一個簡單的字符串長度處理函數作講解並演示如何編寫一個高效的strlen函數。面試
#include <stdio.h>
#define OPTIMIZE 1
#if OPTIMIZE
/*如下代碼段是針對32位CPU深度優化調整後的strlen函數,咱們充分利用CPU的數據寬度,使用int指針去訪問內存數據,每次按照CPU字長去讀取數據,極大地利用了CPU訪問內存的能力。雖然每次讀取一個int型都須要判斷其中是否出現空數據字節(‘\0’),可是依然要比按字節訪問內存提升極大的運行速度。 */
int mystrlen(char *str)
{
/* 爲了不數據指針的自增致使頻繁訪問內存,全部的臨時變量都聲明爲寄存器存儲類型,以提升運行速度 */
register int *tail = (int *)str;
register int value;
register int len = 0;
char *p;
while (1) {
/* 用臨時變量接受讀取的內存值,目的是避免在接下來的判斷表達式中使用*tail以提升運算速度(*tail會讓編譯器生成一條訪存指令,拖慢速度) */
value = *tail;
/* 用if運算來判斷每個字節,以確保若是遇到空字節(‘\0’)則當即結束循環,不然認爲沒有遇到字符串結尾,則將長度計數器增長4 */
if (!(value & 0xff000000) || !(value & 0xff0000)
|| !(value & 0xff00) || !(value & 0xff))
break;
len += 4; /* 長度計數器自增4字節 */
tail++; /* 當前數據指針後移 */
}
p = (char *)tail;
while (*p++ != '\0')
len ++;
return len;
}
#else
/* 如下程序片斷是簡單的字符串長度計算功能,大部分程序員都會使用這種方法,緣由是簡單易於編寫和維護。可是其運行的效率實在不敢恭維,由於其使用了一個char型指針去訪問內存,每次讀取一個字節,嚴重浪費了32位CPU的數據寬度。 */
int mystrlen(char *str)
{
char *tail = str;
while ('\0' != *tail)
tail++;
return tail - str;
}
#endif
/* 如下主程序用來測試編寫的函數速度,方法是用編寫的函數計算長度爲50個字符的字符串一千萬次,並用time函數計算運行總時間。 */
int main()
{
char *str = "12345678901234567890123456789012345678901234567890";
int len;
int i;
for (i = 0; i < 10000000; i++)
len = mystrlen(str);
return 0;
}函數
如下是測試結果:測試
沒有優化後的測試結果:優化
優化後的測試結果:3d