Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
2-1166528410
hgd
2006-12-19 14:40
2007.01.07
Перевод кода из VB


3-1161578262
Rashit
2006-10-23 08:37
2007.01.07
Delphi + MySQL


2-1166214377
FIL-23
2006-12-15 23:26
2007.01.07
как узнать какая по счету линия в memo


2-1166371023
Com
2006-12-17 18:57
2007.01.07
dll


2-1165418062
crasher
2006-12-06 18:14
2007.01.07
панель задач своими руками





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский