Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Поиск в бинарном файле [D5, WinXP]


Страницы:   1 2 ... 5 6 7 8 9 10 11 12 13 14

Dimaxx ©   (2004-09-24 23:32:00) 

Сабж. Нужен алгоритм действительно быстрого поиска последовательности байт любой длины в файлах любого размера (до гигабайта). Читать кусками по-деревенски не катит. Раньше у меня был алгоритм, но с падением Фуджика все пропало.


GuAV   (2004-09-27 00:30:00) [201]

Defunct ©   (27.09.04 00:02) [61]

понял.
а попробуйте не выносить LoadBuffer, окажется всё проще:
  Repeat
    BlockRead(F, Buffer^, MaxBufferSize, BufSize);

    Result := CompareStrings(Constant, Buffer, BufSize);

    Seek(F, FilePos(F) - Length(Constant));
  Until Result Or (BufSize<MaxBufferSize);


в своём подобном коде на pascal я просто запоминал позицию в искомой строке.
дело в том что он был не на асм. а в этом я искал того же.


> Вот и закончились выходные...

а у нас ещё полчаса выходных.


Defunct   (2004-09-27 00:23:00) [202]

Вот и закончились выходные...

2 Dimaxx спасибо за вопрос


Defunct   (2004-09-27 00:07:00) [203]

>Не учтено. проверка должна быть в CharPos.
>В измененном варинте добавляю проверку:


Test  ECx,ECx
Jz    @@NotMatch


хотя по большому счету, буфер нулевой длинны не должен допускаться к проверке. Ведь нам не нужно тормозить поиск, только для того чтобы установить частный случай. так что этот нововведенный код выбросить, а проверку поставить в основной процедуре:

If BufSize> Length(Constant) Then
Result := CompareStrings(@Constant[1], Buffer, BufSize);


Defunct   (2004-09-27 00:02:00) [204]

GuAV ©   (26.09.04 23:47) [58]

Ха, наконец-то интересный разговор.

2. (самое интересное) как обрабатывается ситуация когда часть строки в одном буфере, часть в другом ?

вот ответ:
..
Sub  ECx,EAx
Cmp  ECx,EBx
Jb   @@Exit_False
..

..
SeekPos := SeekPos - Length(Constant);
..


3. Зачем танцы с SeekPos учитывая что строка одна ?
Думаю это отпадает после ответа на 2.

1. Как обрабатывается буфер нулевой длины ?
Не учтено. проверка должна быть в CharPos.
В измененном варинте добавляю проверку:

Asm
//  Xchg  EDx, EDi

 Push  ECx
  Test  ECx,ECx
 Jz    @@NotMatch

 Repne ScasB
 MOV EAX, [ESP] // Pop   EAx
 Jnz   @@NotMatch
 Sub   EAx, ECx
//  Xchg  EDx, Edi
 POP   ECX
 CLC
 Ret
@@NotMatch:
// Xor   EAx, EAx
// Dec   EAx
 STC
//  Xchg  EDx, Edi
 POP   ECX
End;


Это было действительно дельное замечание. спасибо.


GuAV   (2004-09-26 23:59:00) [205]


> PPS: to GuruAV, прочитайте [10] сверьте время [10] и [15]
> сколько ушло на реализацию алгоритма (писал с нуля), посмотрите
> цель написания кода[10] и прочитайте [16]. теперь скажите,
> как бы на моем месте вы среагировали на [21].

Ок. Я Вас понял. Поймите и меня: мне код в [15] показался стрёмным именно из-за [21] [26] и особенно [27] в начале. Из-за этго показалось, что писал чайник. Я высказал свои опасения в [21].

зы: перерегистрироваться не хочу, лучше воспользуюсь полем реальное имя.


GuAV   (2004-09-26 23:48:00) [206]


> Согласитесь, задача, хоть и сравнительно простая, но имеет
> ой как много неприятных моментов.

Вот тут безоговорочно согласен!


GuAV   (2004-09-26 23:47:00) [207]


> С моей точки зрения, фукция должна игнорировать сей факт,
> ее назначение поиск строки в файле. А раз нет файла, то
> нет и строки, все четко. Не надо никаких исключений, от
> них только программа захламляется.

Не согласен. Исключения полезны, особенно если умеешь с ними обращася.

> Естессно оптимизировать мона и дальше

Да.

Вопросы по коду (что я не понял):

1. Как обрабатывается буфер нулевой длины ?
2. (самое интересное) как обрабатывается ситуация когда часть строки в одном буфере, часть в другом ?
3. Зачем танцы с SeekPos учитывая что строка одна ?


Defunct   (2004-09-26 23:41:00) [208]

GuAV ©   (26.09.04 23:26) [55]

Вот, давно пора было.
Это из серии анекдотов про Илью Муромца, "Как трезвый так золотой человек, как выпьет ну просто хавайся"

Любителям стремного кода надо еще добавить флаг C вместо проверки EAX на -1

Asm
//  Xchg  EDx, EDi
Push  ECx
Repne ScasB
MOV EAX, [ESP] // Pop   EAx
Jnz   @@NotMatch
Sub   EAx, ECx
//  Xchg  EDx, Edi
POP   ECX
CLC
Ret
@@NotMatch:
// Xor   EAx, EAx
// Dec   EAx
STC
//  Xchg  EDx, Edi
POP   ECX
End;

Call CharPos
// Pop  ECx
// Xchg EDx, EDi
Jnc  @@CompareNextChars
Sub  ECx,EAx
Cmp  ECx,EBx
Jb   @@Exit_False

// Cmp  EAx, 0FFFFFFFFh
// Jnz  @@CompareNextChars


Естессно оптимизировать мона и дальше


Defunct   (2004-09-26 23:33:00) [209]

> И потом, подпрограмма не должна оставлять факт остсутсвия файла без внимания, она должна возбудить исключение по этому делу.

С моей точки зрения, фукция должна игнорировать сей факт, ее назначение поиск строки в файле. А раз нет файла, то нет и строки, все четко. Не надо никаких исключений, от них только программа захламляется.

PS: Как код?
сравните оба по скорости, [15] и [40] разницы практически нет.

PPS: to GuruAV, прочитайте [10] сверьте время [10] и [15] сколько ушло на реализацию алгоритма (писал с нуля), посмотрите цель написания кода[10] и прочитайте [16]. теперь скажите, как бы на моем месте вы среагировали на [21].

Согласитесь, задача, хоть и сравнительно простая, но имеет ой как много неприятных моментов.


GuAV   (2004-09-26 23:26:00) [210]

любителям стрёмного асм-кода посвящается...
Function CharPos:Integer;Assembler;
 { in: AL: Char
       EDI: Pointer to buffer
       ECX: Size of buffer
   out: EAX: Result
       ECX: Size of buffer
   }
Asm
//  Xchg  EDx, EDi
 Push  ECx
 Repne ScasB
 MOV EAX, [ESP] // Pop   EAx
 Jnz   @@NotMatch
 Sub   EAx, ECx
//  Xchg  EDx, Edi
 POP   ECX
 Ret
 @@NotMatch:
 Xor   EAx, EAx
 Dec   EAx
//  Xchg  EDx, Edi
 POP   ECX
End;

Function CompareStrings(Constant: string; Buffer:Pointer; BufSize:Integer):Boolean;Assembler;
Asm
Push EDi
Push ESi
Xchg EAx, ESi
Mov  EDi, EDx
Xchg EDx, EBx
Mov  EBx, [ESi-4]
Dec  EBx

@@Scan:
Mov  Al, [ESi]
// Xchg EDx, EDi
// Push ECx
Call CharPos
// Pop  ECx
// Xchg EDx, EDi


GuAV   (2004-09-26 23:25:00) [211]

<off>

> Вопрос в толковании

да, я про 216 :)
</off>


Anatoly Podgoretsky   (2004-09-26 23:21:00) [212]

GuAV ©   (26.09.04 23:06) [52]
Guru AV

Вопрос в толковании


GuAV   (2004-09-26 23:06:00) [213]

Defunct ©   (26.09.04 22:22) [51]

Про safecall может и так, но это было бы не правильное её применение.

т.к. любая функция Delphi, возвращающая Integer возвращает его в EAX

{$O-}
{$OPTIMIZATION OFF}
function Return555: Integer; stdcall; assembler; // или pascal анаолгично
asm
 MOV  EAX, 555;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Caption:=IntToStr(Return555);
end;



>  Guru AV

:) Это идея.


Defunct   (2004-09-26 22:22:00) [214]

> Я имел ввиду там способ проверки валидности указателя через try... except, который неправильный.

Так то были вы? :)
Извините, но мне так понравилась эта фраза, что я ее еще раз повторю.

GuAV ©   (26.09.04 02:01) [50]
> т.е. способ try..except - пример неправильного написания программы.


> DWORD вариант я пока не отмёл, т.к. можно не сдвигать строку, а пройти буфер 4 раза с разными младшими битами ESi и EDi.

Удачи. потестируем ваше решение, смотрится хорошо но существенного выиграша в скрости не даст, см [32] пункты "что мы проиграем? - 1,3" плюс добавляется еще чаcтный случай сброса поиска.

Mov  Result, EAx  // This is odd when optimization is on
т.к. любая функция Delphi, возвращающая Integer возвращает его в EAX. (кроме D1, где в AX)
<off>имхо неверный коментарий более грубая ошибка чем неверный код</off>


Вы кстатити как поняли коментарий?
Там написано "при оптимизации - это лишнее"
далее смотрите пост [16], где я отмечаю, что код требует оптимизации, жаль автору такая интересная задачка недосталась.

Function ...;assembler;safecall;
Function ...;assembler;pascal;
Мало ли что, может захочется в DLLку вставить этот код и использоваться safecall. Кстати, вполне актуальное место для приведенного [15] кода.

> Даже не было опровержение метода предолженного default (c)
Какого метода? Ссылку давайте, сыт погорло голословными утверждениями.

> Сейчас поставил Delphi, попробую этот код в работе...
аж дух затаил, жду с нетерпением что скажет Guru AV.


Dimaxx   (2004-09-26 22:13:00) [215]

Только отлучился, а тут уже темку раздули... :-)


GuAV   (2004-09-26 21:41:00) [216]


> ESi и EDi.

только EDi точнее.


GuAV   (2004-09-26 21:38:00) [217]


> Неожиданно интересная ветка оказалась...


поэтому продолжаю здесь

Defunct ©   (26.09.04 20:12) [46]

Я имел ввиду там способ проверки валидности указателячерез try... except, который неправильный. тут я предлагаю использовать конструкцию try..finally и хранить исключения для вызавашего кода. Это вещи разные, имхо даже противоположные. Вызывающая подпрограмма не должна также использовать try..except в том виде в каком Вы предложили её в той ветке.


>  (не ругань а код и комментарии) мне например было очень
> интересно.

:) мне тоже особенно
Mov  Result, EAx  // This is odd when optimization is on
т.к. любаяфункция Delphi, возвращающая Integer возвращает его в EAX. (кроме D1, где в AX)
<off>имхо неверный коментарий более грубая ошибка чем неверный код</off>

по поводу развития мысли кода:

DWORD вариант я пока не отмёл, т.к. можно не сдвигать строку, а пройти буфер 4 раза с разными младшими битами ESi и EDi.

Даже не было опровержение метода предолженного default (c)

Сейчас поставил Delphi, попробую этот код в работе...


> уже над нами наверно весь форум смеется

я кажется не говорю ничего смешного.
моё упорство может показаться кому-то смешным, ну вот такой я есть.


Sergey_Masloff   (2004-09-26 20:18:00) [218]

>уже над нами наверно весь форум смеется
Если вы когда меряетесь еще и код будете продолжать приводить то лучше здесь продолжайте. Неожиданно интересная ветка оказалась...
В любом случае спасибо. Интерес конечно чисто академический но читать (не ругань а код и комментарии) мне например было очень интересно. Так что в любом случае спасибо ;-)


Defunct   (2004-09-26 20:12:00) [219]

> Если процедура написана по правильному, т.е. чтение в блоке try то в ситуации когда файл не существует, исключение подумется при первом чтении.

Кто-то, конечно же это были не вы, а ваш двойник, в смежной ветке с заголовком New() сказал золотую фразу:

GuAV ©   (26.09.04 02:01) [50]
> т.е. способ try..except - пример неправильного написания программы.

Вы сами себе противоречите.

PS: пора заканчивать, уже над нами наверно весь форум смеется "hot china guys", ICQ у меня указан в анкете.


GuAV   (2004-09-26 19:59:00) [220]


> Если процедура написана по правильному, т.е. чтение в блоке
> try то в ситуации когда файл не существует, исключение подумется
> при первом чтении.

разумеется, оно подымется в любом случае.
просто оно будет правильно обработано,
> Если процедура написана по правильному
.

И потом, подпрограмма не должна оставлять факт остсутсвия файла без внимания, она должна возбудить исключение по этому делу.


Страницы:   1 2 ... 5 6 7 8 9 10 11 12 13 14

Наверх

Титульная страница Поиск, карта сайта Написать письмо