Форум: "Прочее";
Текущий архив: 2007.01.07;
Скачать: [xml.tar.bz2];
ВнизCompareMem Найти похожие ветки
← →
Rouse_ © (2006-12-13 23:35) [0]Это просто теоретический вопрос.
Надеюсь что все знают, что в 2006-ой Delphi данная функция идет в составе среды под лицензийе MPL в авторстве Александра Шарахова.
http://www.delphimaster.ru/cgi-bin/anketa.pl?id=1084952164
Что меня немного удивило в данной функции, это то, что если третий параметр функции (размер данных, приходит в ЕСХ) ноль, то функция выходет с True.
Теперь вопрос: задача функции является сравнение двух блоков данных, должна ли она возвращать True если данных нет?
← →
Rouse_ © (2006-12-13 23:38) [1]Мы просто сегодня с jack128 по этой теме что-то заспорили...
Его логика - данные равны даже если их размер нулевой.
Моя логика - если размер нулевой, то данных то собственно и нет, поэтому результат должен вернуться False т.к. сравнивать нечего...
← →
Vga © (2006-12-13 23:40) [2]Моя логика - отсутствие данных равно отсутствию данных.
← →
Vga © (2006-12-13 23:41) [3]А вот если раньше в Delphi эта функция была реализована иначе, то правильно будет так, как работала прежняя версия (если я правильно понял)
← →
Gero © (2006-12-13 23:42) [4]> [1] Rouse_ © (13.12.06 23:38)
> Его логика - данные равны даже если их размер нулевой.
А почему нет, между ними ведь нет отличий.
← →
Rouse_ © (2006-12-13 23:43) [5]Раньше True, но ИМХО это не правильно, ведь функция не выполнила сравнения данных...
← →
Kerk © (2006-12-13 23:45) [6]> [5] Rouse_ © (13.12.06 23:43)
s1,s2: string;
s1 := "";
s2 := "";
if s1 = s2 then
...
Тоже самое
← →
Vga © (2006-12-13 23:45) [7]> [5] Rouse_ © (13.12.06 23:43)
Тогда никаких вопросов - правильно, т.к. совместимость.
← →
Rouse_ © (2006-12-13 23:49) [8]Тут как понять, если одним из условий выхода является размер данных, то да, но Compare и особенно Mem выполненно то небыло, почему тогда выход с единицей в ЕАХ?
← →
Юрий Зотов © (2006-12-13 23:50) [9]Функция должна возвращать integer - да, нет, не знаю.
← →
Petr V. Abramov © (2006-12-13 23:52) [10]> ведь функция не выполнила сравнения данных...
и денег ей давать нефиг :)
подойдем по-другому: если данных не было и программа пойдет по true, она будет глючить? в 90% случаев - нет. Если два пустых буфера не равны, будет глючить? :)))
← →
Rouse_ © (2006-12-13 23:53) [11]
> Функция должна возвращать integer - да, нет, не знаю.
Юр, век лампочек прошел :)
Кстати, что также удивило, ни в старой реализации ни в новой нет банального test ecx,ecx после которого можно спокойно выходить. Решение об этом происходит после по факту....
← →
palva © (2006-12-13 23:56) [12]Наверно алгоритм такой. Сначала выходной переменной присваивается True, потом идет цикл: сначала сравниваются первые байты, потом вторые и т. д. Как только байты не совпали, выходной переменной присваивается False и break из цикла. А если цикл вообще не работал, то так и осталось True.
← →
Rouse_ © (2006-12-13 23:56) [13]
> если данных не было и программа пойдет по true, она будет
> глючить?
Дык... я просто был уверен что не нужно утруждаться излишней проверкой на размер и она вернет ложь, оказалось не так. Вынес код к себе в модуль и поправиль, так проще чем кучу проверок ставить :)
← →
Rouse_ © (2006-12-13 23:58) [14]
> palva © (13.12.06 23:56) [12]
В старой было тупо через REPE сделано, у Sha все красивее на несколько порядков, но всеравно, такая мелочь казалось бы ... :)
← →
TUser © (2006-12-14 00:04) [15]зависит от задачи
Есть последовательности двух генов, одна длины ноль и другая - длины ноль. Ясно, чтоэто глюки интернета, базы данных, программы, бухого молекулярного биолога и пр. Данные по определению не равны, т.к. за нулевой длиной скрываются сотни неизвестных букафф.
Есть координаты атомов лиганла. Надо сравнить лиганды в двухз структурах. Если везде длина записи об атомах лиганда - ноль, то значит полное совпадение - нигде лиганда нет.
← →
Rouse_ © (2006-12-14 00:07) [16]Ииии, хорошь ругаца :))
Вопрос в чем, какого спрашивается функция возвращает TRUE если она не произвера сравнение данных (не произвела однозначно, т.к. тест на длинну данных ни там ни ниже нет)function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;
asm
PUSH ESI
PUSH EDI
MOV ESI,P1
MOV EDI,P2
MOV EDX,ECX
XOR EAX,EAX
AND EDX,3
SAR ECX,2
JS @@1 // Negative Length implies identity.
REPE CMPSD
JNE @@2
MOV ECX,EDX
REPE CMPSB
JNE @@2
@@1: INC EAX
@@2: POP EDI
POP ESI
end;
← →
Sha © (2006-12-14 00:13) [17]Мне кажется, тут логика такая: найдены отличия = false, не найдены = true.
Вроде логично.
Насчет провеки ecx в начале точно не помню.
Но если она не делается, то, значит, потому, что из-за нее тормоза были.
Функция часто используемая, поэтому хотелось сделать,
чтоб все быстрее крутилось...
← →
Rouse_ © (2006-12-14 00:26) [18]
> Sha ©
Спасибо за обьяснение, т.е. упор шел на то что все-же сравниваться будут блоки данных не нулевого размера? Ок, я просто сделал тест ма мультимедийных таймерах... Почти идентично, но с разбросом небольшим, не выяснить дает ли тормоза (ну конечно же дает, но слишком много времени нужно длать чтобы значения разброса стали значительны).
По поводу тормозов
> Kerk © (13.12.06 23:45) [6]
> > [5] Rouse_ © (13.12.06 23:43)
>
> s1,s2: string;
>
> s1 := "";
> s2 := "";
> if s1 = s2 then
> ...
>
> Тоже самое
Пардон, не ответил, это не тоже самое, в данном примере сравниваются два 8-байтных блока памяти, что сам понимаешь никак не сравниться с нулевым размером данных.
← →
Vga © (2006-12-14 00:28) [19]> Пардон, не ответил, это не тоже самое, в данном примере
> сравниваются два 8-байтных блока памяти, что сам понимаешь
> никак не сравниться с нулевым размером данных.
А я где-то читал, что пустая строка - это nil
← →
Rouse_ © (2006-12-14 00:31) [20]
> А я где-то читал, что пустая строка - это nil
Больше такого не читай :)
← →
Petr V. Abramov © (2006-12-14 00:35) [21]> Rouse_ © (13.12.06 23:56) [13]
ай... противоречит принципу полковника Скалозуба :)))
не в части книг, конечно :)))
← →
Sha © (2006-12-14 00:39) [22]> Rouse_ © (14.12.06 00:26) [18]
> упор шел на то что все-же сравниваться будут блоки данных не нулевого размера?
Да. Сравнение пустых блоков, по идее, редкая операция.
Тем не менее, и они сравниваются быстро.
Джон О"Харроу собирал статистику.
Как ни странно, чаще всего программы работают со строками 1 байт :)
И больше половины обращений, кажется, приходится на строки до 16 байт.
Идея состояла не только в написании быстрой функции, но и в обеспечении
максимального быстродействия на коротких блоках.
← →
Rouse_ © (2006-12-14 00:39) [23]Петь, ну не люблю писать нечитабельный код просто,
лишние проверки - глаз теряет мысль при чтении,
сотворил CompareMemEx - генофонд не трогал :)
← →
Sha © (2006-12-14 00:44) [24]> А я где-то читал, что пустая строка - это nil
Так и есть.
Можно, правда, вручную сделать строку нулевой длины, которая не nil, но
это для специльных случаев используется.
← →
Rouse_ © (2006-12-14 00:45) [25]
> Sha ©
Ну мы люди военные, нам более Сунь-Цзы естественнен в плане производительности :)
"Поэтому мудрый полководец должен отнимать провиант у врага. Один бушель зерна противника стоит двадцати наших; одна единица фуража стоит двадцати наших." ;)
← →
Rouse_ © (2006-12-14 00:46) [26]
> Sha © (14.12.06 00:44) [24]
> > А я где-то читал, что пустая строка - это nil
>
> Так и есть.
Строка как бы не есть чистый PChar, бо размер имеет и счетчик ссылок :)
← →
Vga © (2006-12-14 00:49) [27]> [26] Rouse_ © (14.12.06 00:46)
Как я читал, если строка пустая, то память, выделенныя строке, просто освобождается. А переменная соответственно заnilивается.
← →
Rouse_ © (2006-12-14 00:52) [28]Строка в пределах видимости функции как бы существует, раз она видима, значит рефы на нее в примере керка возведены как минимум в единицу. За пределами видимости никто и не спорит.
← →
Petr V. Abramov © (2006-12-14 00:55) [29]> Петь, ну не люблю писать нечитабельный код просто,
а кто любит-то? но, тем не менее, вариант, когда строка пустая - увы, реальный. Поэтому обработать его надо, не завязываясь на результат CompareMem, исключая случаи, когдв ты ТОЧНО ЗНАЕШЬ( и.е. не поленился вспомнить, что про это надо подумать :), что true или false этой ф-ции на пустой строке не приведет к глюку.
Про п-ка Скалозуба: всякие е-нутые ситуации обрабатывать там, где они могут возникнуть, а не где могут иметь последствия. В большинстве случаев обработка будет где-то глубоко в ya.molodetz.system, всегда работать и никого не ...
← →
Sha © (2006-12-14 00:55) [30]Для видимой строки после
s="";
получим
pointer(s)=nil
что легко проверить
← →
Eraser © (2006-12-14 00:58) [31]> [27] Vga © (14.12.06 00:49)
procedure _LStrClr(var S);
{$IFDEF PUREPASCAL}
var
P: PStrRec;
begin
if Pointer(S) <> nil then
begin
P := Pointer(Integer(S) - Sizeof(StrRec));
Pointer(S) := nil;
if P.refCnt > 0 then
if InterlockedDecrement(P.refCnt) = 0 then
FreeMem(P);
end;
end;
{$ELSE}
asm
{ -> EAX pointer to str }
MOV EDX,[EAX] { fetch str }
TEST EDX,EDX { if nil, nothing to do }
JE @@done
MOV dword ptr [EAX],0 { clear str }
MOV ECX,[EDX-skew].StrRec.refCnt { fetch refCnt }
DEC ECX { if < 0: literal str }
JL @@done
LOCK DEC [EDX-skew].StrRec.refCnt { threadsafe dec refCount }
JNE @@done
PUSH EAX
LEA EAX,[EDX-skew].StrRec.refCnt { if refCnt now zero, deallocate}
CALL _FreeMem
POP EAX
@@done:
end;
{$ENDIF}
← →
Rouse_ © (2006-12-14 01:03) [32]Хм, а чтоже еще мы можем получить при Pointer(S1[0]) там же размер лещит нулевой, который при приведении равен NIL?
← →
MikePetrichenko © (2006-12-14 01:04) [33]А вот в WinAPI практически все функции сравнения начинаются с сравнения длины. Если не равна длина, то и данные не равны...
← →
Vga © (2006-12-14 01:04) [34]> [31] Eraser © (14.12.06 00:58)
Да, я уже на это в дебаггрере посмотрел :) Довольно любопытно. Правда, я ошибся с освобождением памяти - она освобождается только если счетчик ссылок равен нулю, а я в [27] сказал не так :(
← →
Sha © (2006-12-14 01:08) [35]Нет.
Pointer(s) всегда возвращает адрес первого символа строки
(или того места, где он мог бы быть в случае пустой строки :)
Это просто приведение типа, можно убедиться в отладчике.
← →
Sha © (2006-12-14 01:09) [36]Последнее к Rouse_ © (14.12.06 01:03) [32] относится
← →
Rouse_ © (2006-12-14 01:13) [37]Саш, мне стыдно такое тебе говорить, но...
if Poiner(S1) = nil then
cmp dword ptr [ebp - $04], $00
← →
Eraser © (2006-12-14 01:13) [38]> [33] MikePetrichenko © (14.12.06 01:04)
дык чтобы определить в PChar длину - нужно найти, где она заканчивается, это не мгновенная операция.
> [32] Rouse_ © (14.12.06 01:03)
дык это ж compiler magic, на самом деле это не начало строки. BDS 2006 вообще не дает к ниму напрямую обращаться.
хотя мож я не совсем уловил, что ты хотел сказать ... )
← →
Sha © (2006-12-14 01:15) [39][ebp - $04] как раз и есть адрес первого символа )
← →
Sha © (2006-12-14 01:16) [40]вернее места, где он лежит
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2007.01.07;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.011 c