Я пишу процедуру, чтобы найти строку в указанном блоке памяти во встроенном (ARM Cortex M0 @ 16MHz) приложении, и мне интересно, почему две разные версии, которые я написал, выполняются на разных скорости.оптимизация скорости памяти strstr (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;
}
memstr последовательно 1us быстрее, чем при нахождении memstr2 строку 7 символов в диапазоне от 20 до 200 байт памяти. Например, найдя 7-значную строку в 110 байтах, memstr принимает 106us, а memstr2 принимает значение 107us. 1us может показаться неважным, но во встроенном приложении, где каждый тик имеет значение, это недостаток.
Вид вопроса о бонусе: Это также побудило меня написать мою собственную strstr, которая быстрее, чем фондовый strstr (например, поиск 7-символьной строки в 207-символьной строке принимает 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_ ничего не говорит о вашей работе. Кроме того, у вашего микросистемы есть состояния ожидания вспышки или состояния ОЗУ (то есть, выборки команд, доступ к данным или оба более дорогих, чем ожидалось)? – Notlikethat