Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.117.107.90] |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Я делаю так:
сравниваю побайтово символы строки1 и строки2, если хоть один не совпадает то строки не совпадают... Нужно сделать быстрее. Подскажите какие ещё варианты есть? |
Сообщ.
#2
,
|
|
|
Не понимаю, куда такая скорость. Я делал прогу, там надо было не просто сравнивать, а производить поиск сочетаний в вводимом слове. Сочетаний было около 28000, всё должно было обрабатываться в хуке во время печати на клаве. Функции CString действительно тормозили, так как там постоянно память перевыделялась, но Cи Runtime функции справились отлично!
|
Сообщ.
#3
,
|
|
|
ИМХО
Команда ассемблера cmpsb спасет отца русской демократии |
Сообщ.
#4
,
|
|
|
strcmp тоже вроде быстро пашет, всяко быстрее самописного цикла
|
Сообщ.
#5
,
|
|
|
2kourov :
Понимеешь программа должна проанализировать сотни тысяч или даже миллионы строк... и побыстрее 2DemonM : В моём случае strcmp не поможет... |
Сообщ.
#6
,
|
|
|
Пишешь примерно следующее (пишу по памяти, поэтому за ошибки не обессудь):
int len1 = strlen(s1); int len2 = strlen(s2); if (len1 != len2) return false; bool ret_val = false; _asm { mov esi, str1 mov edi, str2 mov ecx, len1 rep cmpsb jnc exit mov ret_val, 1 exit: } return ret_val; Поиск длины строки тоже можешь завернуть на ассемблере. Если сделаешь функции инлайновыми, то быстрей алгоритма ты не найдешь. |
Сообщ.
#7
,
|
|
|
Кстати, вот пример из CRTL VC++ (файл strncmp из дериктории vc98\crt\src\intel\):
CODESEG public strncmp strncmp proc \ uses edi esi ebx, \ first:ptr byte, \ last:ptr byte, \ count:IWORD mov ecx,[count] ; cx=max number of bytes to compare jecxz short toend ; it's as if strings are equal mov ebx,ecx ; bx saves count mov edi,[first] ; di=first pointer (es=segment part) mov esi,edi ; si saves first pointer xor eax,eax ; ax=0 repne scasb ; count bytes neg ecx ; cx=count - strlen add ecx,ebx ; strlen + count - strlen okay: mov edi,esi ; restore first pointer mov esi,[last] ; si = last pointer repe cmpsb ; compare strings mov al,[esi-1] xor ecx,ecx ; set return value = 0 cmp al,[edi-1] ; last-first ja short lastbig ; <last is bigger> je short toend ; <equal> ;jb short firstbig ; <first is bigger> firstbig: dec ecx ; first string is bigger dec ecx ; make FFFE so 'not' will give 0001 lastbig: ; last string is bigger not ecx ; return -1 toend: mov eax,ecx ; return value ret ; _cdecl return strncmp endp end |
Сообщ.
#8
,
|
|
|
2Flex Ferrum:
К сожалению тут strlen уже всё тромозит... если я поставю хтабы только сравнение на разность строк, даже не сравнивая 2 массива, то это уже дольше работает чем так как я делю(как в самой первой месаге написанно) |
Сообщ.
#9
,
|
|
|
В той же директории лежит модуль strlen.asm. Объедени это в одну функциию, написанную на асме, или посмотри, как это реализовано в модуле strcmp.asm.
|
Сообщ.
#10
,
|
|
|
Возможно, поможет такая стратегия (я использовал нечто похожее при написании LZ77-сжатия, и это помогло):
Сравниваем не a[0]==b[0]; a[1]==b[1]; a[2]==b[2]..., а: L-длинна строки a[0]==b[0]; a[L-1]==b[L-1]; a[1]==b[1]; a[L-2]==b[L-2]; т.е. начинаем сравнивать с начала и конца. |
Сообщ.
#11
,
|
|
|
int find_str(char* buf1,char* buf2,int len1,int len2)
{ for(int i=len;i>=0;i--){ if(!buf1[i]|buf2[i]){return -1}; //строки не совпадают! }; return 0; //строки совпадают }; вот как ща сделал... Кто быстрее сам алгоритм может проедложить?(именно алгоритм а не оптимезацию на асме) |
Сообщ.
#12
,
|
|
|
Может хотел написать вот так:
int find_str(char* buf1,char* buf2,int len1,int len2) { for(int i=len;i>=0;i--){ if(!(buf1[i]^buf2[i])){return -1}; //строки не совпадают! // вот тут поправил | на ^ и скобоцки расставил }; return 0; //строки совпадают }; надеюсь, просто пропущен код, который сравнивает len1 и len2, кроме того где-то там же появляется третья переменная len, видимо меньшая из них. |
Сообщ.
#13
,
|
|
|
2 Sourcer: Тебе Flex Ferrum правильно предложил напишу функцию на ассемблере. На Си ты все равно быстрее не напишешь, какой бы ты алгоритм не придумал. Задача тривиальна, алгоритм один, все зависит от реализации.
Предлагаю тебе текст функции и могу заявить, что быстрее реализации ты не придумаешь. __declspec(naked) int find_str(char* buf1, char* buf2, int len1, int len2) { __asm { push esi push edi xor eax,eax mov ecx,len1 cmp ecx,len2 jne exit1 mov esi,s1 mov edi,s2 mov edx,ecx shr ecx,2 jz cmpbytes repe cmpsd jne exit1 cmpbytes: mov ecx,edx and ecx,3 repe cmpsb jne exit1 inc eax exit1: pop edi pop esi ret } } __declspec(naked) не убирай, чтобы компилятор свой пролог и эпилог не вставлял, он тоже может подтармаживать |
Сообщ.
#14
,
|
|
|
Если строки длинные, возможно быстрее будет использовать не CMPSB, а CMPSD.
|
Сообщ.
#15
,
|
|
|
Sourcer:
А что, побитовое OR или XOR работают быстрее обычного стравнения? И еще. Когда тебе нужен действительно быстрый алгоритм - без ручной оптимизации на ассемблере не обойтись - каким бы ни был хорошим компилятор, все равно он не соптимизирует код лучше человека (в некоторых случаях). |