![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Поиск в бинарном файле [D5, WinXP]
Dimaxx © (2004-09-24 23:32:00)
Страницы: < 1 2 ... 5 6 7 8 9 10 11 12 13 14 >
Сабж. Нужен алгоритм действительно быстрого поиска последовательности байт любой длины в файлах любого размера (до гигабайта). Читать кусками по-деревенски не катит. Раньше у меня был алгоритм, но с падением Фуджика все пропало.
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 то в ситуации когда файл не существует, исключение подумется
> при первом чтении.
разумеется, оно подымется в любом случае.
просто оно будет правильно обработано,
> Если процедура написана по правильному
.
И потом, подпрограмма не должна оставлять факт остсутсвия файла без внимания, она должна возбудить исключение по этому делу.