Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.01.07;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.034 c
15-1166455220
dr_craigan
2006-12-18 18:20
2007.01.07
открытие картинок с помощью ...


15-1166087509
boriskb
2006-12-14 12:11
2007.01.07
Подзаработать что ли?


15-1166543799
oldman
2006-12-19 18:56
2007.01.07
Всем спасибо за ответы по видеокарте.


1-1163611249
mmms
2006-11-15 20:20
2007.01.07
Обратится из главной к дочерней форме


1-1163576005
net_daemon
2006-11-15 10:33
2007.01.07
Алгоритмический вопрос по комбинаторике