我正在編寫一個例程以在嵌入式(ARM Cortex M0 @ 16MHz)應用程序中的指定內存塊中查找字符串,並且想知道爲什麼我編寫的兩個不同版本運行在不同的速度。自定義memstr(strstr)速度優化
char* memstr(char* mem, uint32_t n, char* str) {
if((str[0] == '\0') || (n == 0)) return NULL;
uint32_t i = 0;
char* max_mem;
max_mem = mem + n;
while(mem < max_mem) {
if(*mem != str[i]) {
mem -= i;
i = 0;
} else {
if(str[i+1] == '\0') return mem - i;
i++;
}
mem++;
}
return NULL;
}
char* memstr2(char* mem, uint32_t n, char* str) {
if((str[0] == '\0') || (n == 0)) return NULL;
uint32_t c = 0;
uint32_t i = 0;
while(c < n) {
if(mem[c] != str[i]) {
c -= i;
i = 0;
} else {
i++;
if(str[i] == '\0') return &mem[c - i + 1];
}
c++;
}
return NULL;
}
當在20和200字節的內存之間找到7個字符的字符串時,memstr始終比memstr2快1us。例如在110個字節中找到7個字符的字符串,memstr需要106us,memstr2需要107us。 1us可能聽起來並不是什麼大不了的事情,但在嵌入式應用程序中,每個tick都有問題,這是一個缺點。
一種獎勵問題:這也促使我編寫自己比strstr更快的strstr(例如,在207字符串中查找7個字符的字符串需要my_strstr 236us和strstr 274us)。這有什麼不對,因爲strstr必須相當優化?
char* my_strstr(char* str1, char* str2) {
uint32_t i = 0;
if(str2[0] == '\0') return NULL;
while(*str1 != '\0') {
if(*str1 != str2[i]) {
str1 -= i;
i = 0;
} else {
i++;
if(str2[i] == '\0') return (str1 - i - 1);
}
str1++;
}
return NULL;
}
用你最後一個函數,我想'my_strstr(「sssmith」,「ssmith」)'返回NULL,這是錯誤的。 –
Mooing Duck:好點,我已修復 – user1228123
你的反彙編是什麼樣的?在我自己編譯它們之後,兩個例程之間並沒有什麼特別顯着的區別(實際上'memstr'稍大一點,並且比'memstr2'多一個分支,通常可能將它定位爲較慢的分支),但顯然_my_編譯器沒有提及你的性能。此外,你的微處理器是否有閃存或RAM等待狀態(即取指令,數據訪問還是比預期更昂貴)? – Notlikethat