· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Быстрый поиск в массиве

. 1 . 2 . 3 . >>

Посл.отвђт Сообщенiе


Дата: Сен 8, 2004 12:07:16

Заранее извиняюсь если тема немного не туда, но вроде под вынь32.
Я из сети получаю пакет данных(обычный массив типа char*) и в нём надо найти кодовую последовательность.(например 55АА=) ). Причём код очень кретичен к скорости. (Сам знаю асм(но не очень хорошо), но надо писать на С++, поэтому наверно асмовская вставка). можно конечно банальным for'ом, но может есть решение поэлегантнее? Заранее спасибо


Дата: Сен 8, 2004 13:00:11

под вынь не знаю под Dos что то вроде
при условии что конец масива обозначается нулём
- если иначе то придётся указывать размер масива - и прогонять через цикл
massiv db 'asdsadktw452984523945orgj mm cas;',55h,0AAh
       db 'fkhg dfmcssadax;sldk ma;dkadl; a;sdkfsa '     
...
...
          lea si,massiv       ;si на указатель масива
NexSymbol:lodsb               ;получаем в al символ
          or al,al            ;Код ноль?
          jz ExitFind         ;угу - сваливаем 
          cmp al,55h          ;Первый символ нашей 
                              ;последовательности? 
          jnz NexSymbol       ;неа - идём смотреть следующий 
          lodsb               ;да наш - получаем следующий
          cmp al,0AAh         ;следующий наш?
          jz Found            ;ага - нашли
          dec si              ;нет - уменьшаем указатель
          jmp NexSymbol       ;дальше
ExitFind:
...
...
...
found:
....
....
....
     


Дата: Сен 8, 2004 13:04:24 · Поправил: Same

или так
massiv db 'asdsadktw452984523945orgj mm cas;',55h,0AAh
       db 'fkhg dfmcssadax;sldk ma;dkadl; a;sdkfsa '     
...
...
          lea si,massiv       ;si на указатель масива
NexSymbol:lodsw               ;получаем в ax пару символов
          or al,al            ;У поледнего код ноль?
          jz ExitFind         ;угу - сваливаем 
          cmp ax,0AA55h       ;Это оно?
          jz Found            ;Да - сваливаем
          dec si              ;нет - уменьшаем указатель
          jmp NexSymbol       ;продолжить поиск
ExitFind:
...
...
...
found:
....
....
....


Дата: Сен 8, 2004 13:18:39

Спасибо!=) последний вариант мне особенно понравился!=))
Интересно, а за сколько он успеет просмотреть 20000 байт?
(вопрос конечно глупый, но число тактов наверно приблезительно оценить можно)


Дата: Сен 8, 2004 14:52:40

eXod

Если искомая последовательность наверняка есть в массиве, то можно сделать короче и быстрее исключив проверку на окончание массива:
    lea esi,massiv      ;esi на указатель масива
NexSymbol:lodsw         ;получаем в ax пару символов
    dec esi
    cmp ax,0AA55h       ;Это оно?
    jne short NexSymbol ;Нет - продолжаем 
ExitFind:               ;Здесь окажемся когда найдено.
    ....


Дата: Сен 8, 2004 15:32:10

=) жаль вот только последовательности там может и не оказаться...
Может кто подскажет как можно замерить время выполнения программы? хочу стравнить разные варианты на асм вставках и на чистом с++=) может если скорость будет выше то в итоге вообще оставлю только описание функций/классов, а всё тело буду реализовывать на асме.(полностью к сожалению не получиться, другим надо класс встраивать в свою программку на с++)


Дата: Сен 8, 2004 16:06:40

Просили же вроде не тупой перебор в цикле. Для поиска подстрок в строке нормальные люди используют Боуера-Мура и его производные адаптированные для конкретного случая. Особенно заметен выигрышь на длинных подстроках.
http://algolist.manual.ru/search/esearch/index.php


Дата: Сен 8, 2004 16:06:51 · Поправил: zzzyab

Как испытать на время ? - Делаеш тестовую прогу с большим циклом этой продседуры. Запускаеш в Soft-ice и там показывается время исполнения.Получается что строчные инструкции и смена адресации тормозные (не испльзуй lodsb и word адресацию).
start:
mov	dword ptr [esi],eax
inc	esi
cmp	eax, '55AA' ; char
je	p1:1
inc	esi
inc	esi
inc	esi
jmp	start
p1:
mov	byte ptr [esi],al
cmp	al,'='
jne	start


Дата: Сен 8, 2004 16:26:03

2Dr.Golova огромное спасибо за ссылку!!!!
2zzzyab дык софтайс ещё поставить надо... но помниться после перехода с 9х на НТ(2000) у меня так и не получилось его нормально поставить=( (в смясле не софтайс для 9х, а для НТ... на 2000 не хотел вставать). Может можно как-то программно(то бишь кодом в самой программе)?


Дата: Сен 8, 2004 16:41:32

eXod

поиск по форуму: RDTSС


Дата: Сен 8, 2004 17:00:05

Dr.Golova

Получается тот, кто не использует алгоритм Боуера-Мура ненормальный?

Для данного случая тогда может Алгоритм Сдвига-Или предпочтительней? Как раз для маленьких искомых последовательностей. По сравнению с Боуера-Мура он требует меньше времени как в худшем случае, так и в усредненном варианте.


Дата: Сен 8, 2004 17:34:10 · Поправил: _Juicy

Между прочим, поиск в строке реализован аппаратно - и по идее должен выполняться быстрее такой код:
	_asm {
		mov eax, 0AA55h
		mov ecx, length    ;  в вордах!
		mov edi, pArray
		cld
		repne scasw
		setz al
		mov fFound, al
	}


Дата: Сен 8, 2004 20:10:27

_Juicy

К примеру, у меня такая строка:

pArray db AAh,55h,AAh,55h ... ;-)


Дата: Сен 8, 2004 21:27:18

Верно :)
Можно два раза прогнать, хотя тогда неизвестно, будет ли выигрыш в скорости.


Дата: Сен 8, 2004 22:02:21 · Поправил: boozook

Можно два раза прогнать
зачем? просто нужно scasb использовать...

Можно попробовать распараллелить процесс:
in_str proc
;вход:
;edi - адрес строки
;ecx - длина строки

;выход:
;не найдено - ecx==FALSE
;найдено    - ecx!=FALSE, edi указывает на 0xAA55

	mov ax,0AA55h
	lea ecx,[edi+(ecx-1)-3]

	cmp edi,ecx
	jae eo_long
@@:
	cmp [edi],ax
	je at0
	cmp [edi+1],ax
	je at1
	cmp [edi+2],ax
	je at2
	cmp [edi+3],ax
	je at3
	add edi,4
	cmp edi,ecx
	jc @B		;достаточно больших циклов
eo_long:

	add ecx,3
	sub ecx,edi
	je eo_short
@@:
	cmp [edi+ecx-1],ax ;не факт, что мы найдем первое!
	je atECX
	dec ecx
	jne @B
eo_short:
	ret

atECX:
	 lea edi,[edi+ecx-1]
	 ret
at3:	inc edi
at2:	inc edi
at1:	inc edi
at0:	ret
in_str endp


должно быть быстрее в разы,.. хотя не знаю как там scasb работает...

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.064