- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
/**
* better,faster OLD SCHOOL HACKS ^^
* **/
public static function compareObject(obj1:Object, obj2:Object):Boolean {
var buffer1:ByteArray = new ByteArray();
buffer1.writeObject(obj1);
var buffer2:ByteArray = new ByteArray();
buffer2.writeObject(obj2);
// compare the lengths
var size:uint = buffer1.length;
if (buffer1.length == buffer2.length) {
buffer1.position = 0;
buffer2.position = 0;
// then the bits
while (buffer1.position < size) {
var v1:int = buffer1.readByte();
if (v1 != buffer2.readByte()) {
return false;
}
}
return true;
}
return false;
}
Сравнение объектов сериализацией, по моему такого тут еще не было...
vse_govno 02.04.2013 17:02 # 0
wvxvw 02.04.2013 18:57 # +3
1. Циклические графы свойств делают обход и сравнение нетривиальной задачей.
2. Сравнивать не public свойства - как правило мало толку.
3. Такой метод почти наверняка используется в контексте, где задействована сериализация, и объекты произвольных типов нужно сравнивать по значению.
4. Это дает возможность при удачной реализации IExternalizable сделать эту проверку гораздо более быстрой, чем цикл с обходом всех свойств.
5. [Transient] опять же позволяет исключить какие-то свойства из такого сравнения.
6. Опять же, способ сравнить всяких наследников Proxy в которых перебор свойств может вообще быть бессмысленной задачей.
7. Можно сравнить объекты разных типов (если, например, сериализация настроена так, что на выходе получаем XML), то таким образом можно сравнить с XML.
Эта тема давно и неоднократно поднималась на флешере... Вобщем, не говнокод.
3.14159265 03.04.2013 14:51 # +3
>faster
> OLD SCHOOL HACKS ^^
>var v1:int = buffer1.readByte();
1.Что это за хуйня? Человек претедует на почётное звание байтоёба. А читает в инт и сравнивает байтами. Ёбанный стыд.
var v1:int = buffer1.readInt(); if (v1 != buffer2.readInt()) {
И теоретически наш код ускоряется в 4 раза.
2.Для начала, ради приличия делают элементарные, детские проверки - на null, на идентичность типов, итд.
В общем, говнокод.
PS. Против самого способа сравнения ничего не имею против.
LispGovno 03.04.2013 15:06 # 0
TarasB 03.04.2013 15:06 # +1
Нет, лёгкая небрежность, не криминал.
wvxvw 03.04.2013 15:45 # 0
По реалиям флеша самый быстрый вариант будет bufferA[i] === bufferB[i], т.как вызов функции получается сильно накладным (или можно использовать какой-нибудь пост-процессор, который этот массив представит как DomainMemory, и тогда можно будет использовать инструкции быстрого доступа и читать по 4 байта за раз. Но скорее всего байтов там совсем не много получается. Двузначное число и очень редко трехзначное. Так что не стоит.
3.14159265 03.04.2013 15:54 # 0
Вам виднее.
>Реализация херовая, но задумка годная
Не спорю.
>Лёгкая небрежность, не криминал.
Да если б не коммент faster OLD SCHOOL HACKS не плюсанул бы.
kostoprav 03.04.2013 15:28 # +1
чисто так - private/protected поля тоже сериализуются
> 4. Это дает возможность при удачной реализации IExternalizable сделать эту проверку гораздо более быстрой, чем цикл с обходом всех свойств.
а выделение памяти под буфера нынче бесплатное?
> 5. [Transient] опять же позволяет исключить какие-то свойства из такого сравнения.
а еще можно написать нечто компараторо-подобное, и так же исключить
> 7. Можно сравнить объекты разных типов (если, например, сериализация настроена так, что на выходе получаем XML), то таким образом можно сравнить с XML.
А во что сериализуется XML, полученный на входе?
wvxvw 03.04.2013 15:41 # 0
Про XML вы не поняли: у вас есть XML полученный откуда-то и ваш объект, и вам нужно сравнить XML с этим объектом. Задача возникает очень часто, если нужно показать какие-нибудь данные, которые часто обновляются, и получаются из внешнего источника.
Реализовать Comparator - ага, успехов вам в этом нелегком. Только сначала потрудитесь выяснить сколько головной боли это стоило, например, в той же Яве, и как долго (да, вобщем-то и до сих пор) это было причиной разного рода непредвиденных ошибок. Вы тут одной реализацией не отделаетесь, т.как нужно будет очень много чего предусмотреть.
Как пример: сравниваем два таких объекта:
Ну и это не отменяет проблем с Proxy и наследниками, да и вообще со всякими объектами, к которым уже доступа нет их поменять.
kostoprav 03.04.2013 15:46 # 0
> Ох боже... памяти на этот буффер выделится аж просто немеряно.
А это уже зависит от глубины вложенности полей. Сериализация одного объекта может утянуть за собой граф из 1000 привязанных.
> Реализовать Comparator - ага, успехов вам в этом нелегком. Только сначала потрудитесь выяснить сколько головной боли это стоило, например, в той же Яве, и как долго (да, вобщем-то и до сих пор) это было причиной разного рода непредвиденных ошибок. Вы тут одной реализацией не отделаетесь, т.как нужно будет очень много чего предусмотреть.
Intellij IDEA -> Alt-Insert -> hashCode() and equals() помогает в 99% случаев.
В вашем же примере вы сравниваете ССЫЛКИ. Они как ни странно - разные. В Java есть Arrays.equals() для этого случая.
wvxvw 03.04.2013 15:50 # 0
kostoprav 03.04.2013 15:52 # 0
kostoprav 03.04.2013 16:09 # 0
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/ByteArray.html#toJSON() - кстати, тоже можно заюзать наверное.
wvxvw 03.04.2013 22:17 # +1
AS программисты жалуются на то, что аллокатор медленно работает? А Явисты не? Да даже те, кто пишут на Си - тоже жалуются. Жаловаться - это профессиональная привычка программистов, от языка практически не зависит.
kostoprav 03.04.2013 22:18 # 0
3.14159265 03.04.2013 15:56 # +1
Полагаю если адобе не мудаки, то должны были сделать его ленивым, как потоки.
Если же вывод в примере не идет в потокообразный объект - тогда говно, да.
kostoprav 03.04.2013 15:58 # 0
3.14159265 03.04.2013 16:02 # 0
И только потом только сравнить их?
Безо всякой асинхронности?
kostoprav 03.04.2013 16:03 # +1
3.14159265 03.04.2013 16:11 # +3
wvxvw 03.04.2013 22:32 # 0
kostoprav 03.04.2013 22:46 # +2
wvxvw 03.04.2013 22:54 # +1
Вы собираетесь создавать equals / getHashCode - для всех встроенных объектов? Как, если не секрет? А их есть несколько сотен разновидностей. А к ним в придачу библиотечные классы, которых может быть тысячи. Откуда у вас возьмется столько рвения и терпения их всех написать?
А написать equals, например, для циклических связных списков?
Или для объектов, которые уже реализовали equals, но не так, как вам нужно.
А как вы будете сравнивать представителей класса с представителями его подклассов, и наоборот?
Более того, такая функция скорее всего могла понадобиться для работы с объектами, которые попадают уже в сериализованом виде, и их нужно сравнить с уже имеющимися, чтобы понять нужно ли делать замену, или нет. Такая ситуация часто возникает при работе с флексовыми сервисами типа Блейза, где почти все объекты которыe передаются с сообщениями наследники / экземпляры ObjectProxy - для которого, уж поверьте, очень нетривиально написать equals который бы хоть что-то вменяемое делал.
kostoprav 03.04.2013 23:01 # +1
Я могу просто сравнить свойства.
> Вы собираетесь создавать equals / getHashCode - для всех встроенных объектов? Как, если не секрет? А их есть несколько сотен разновидностей. А к ним в придачу библиотечные классы, которых может быть тысячи. Откуда у вас возьмется столько рвения и терпения их всех написать?
Я думаю, встроенные классы не тупые, и умеют сравниваться. Ну это было бы логично.
> А написать equals, например, для циклических связных списков?
for each? не, не слышал...
> А как вы будете сравнивать представителей класса с представителями его подклассов, и наоборот?
а как тут сериализация поможет? В сериализованном виде дескриптор БУДЕТ отличаться для родителя и потомка - фейл.
> Такая ситуация часто возникает при работе с флексовыми сервисами типа Блейза, где почти все объекты который передаются с сообщениями наследники / экземпляры
И?
wvxvw 03.04.2013 23:15 # 0
Являются ли массивы [1, 2] и [1, 2] одинаковыми? А если x = [1, 2] x[x] = x и y = [1, 2], одинаковы ли x и y? А если это словарь, имеет ли значение тот факт, что ключ в нем равен 1 или "1"? А как вы об этом узнаете?
Вы "думаете" что встроенные классы умеют сравниваться, а в справку не заглянули, но тем не менее спорите?
Сериализация для классов, которые не декларировали registerClassAlias будет делаться так, как будто сериализуется обычный объект, поэтому, если значения полей совпадут, то и будут равны, не важно в какой степени родства находятся.
Сорри, вы либо совсем новичек в этом языке, либо его вообще не знаете. Лучше начните со справки, а потом приступайте к обвинениям.
kostoprav 03.04.2013 23:19 # +1
Зачем нужны такие классы? Это отказ от ООП какой-то, точнее переход на HashMap-oriented OOP.
> Являются ли массивы [1, 2] и [1, 2] одинаковыми?
Да, есть такой цикл - for each называется.
> А если это словарь, имеет ли значение тот факт, что ключ в нем равен 1 или "1"? А как вы об этом узнаете?
Имеет. В 1 случае ключом является число, в другом строка. Почитайте про типизацию, это интересная тема. Хотя судя по комментам, передо мной выходец из PHP и поклонник HashMap-oriented OOP
> Вот жеж... нет, вы не можете просто сравнить свойства. См. пример выше. Свойства могут иметь значения (и очень часто таки имеют такие значения), которые вы "просто" сравнить не можете.
Добавил в цитатник
wvxvw 03.04.2013 23:26 # 0
А по поводу словаря - ну, хорошо, это вы сейчас так решили. А что будет завтра, когда вы решите по-другому? А что, если за вас уже кто-то решил, по-другому? Предположим, узнать есть ли в словаре два разных ключа "1" и 1 не сериализируя его вы вообще совсем никак не сможете. Это скорее недостаток в реализации словаря как такового, но тем не менее, так оно работает и с этим жить.
О, я знаменит, меня теперь начинающие цитируют!
kostoprav 03.04.2013 23:29 # +1
Чего? Я про инкапсуляцию слышал.
> сериализация
В мое время там была абстракция.... Хотя наверное
"чет я совсем отстал от новых веяний в ООП."
roman-kashitsyn 03.04.2013 23:43 # +2
По поводу классов и подклассов - всем будет жить гораздо проще, если base.equals(derived) и derived.equals(base) всегда будут возвращать false. Это правильно в 99.999% случаев, т.е. когда при наследовании не добавляются новые поля. Иначе сложно обеспечить симметрию и транзитивность equals.
kostoprav 03.04.2013 23:46 # 0
А так:
wvxvw 04.04.2013 00:12 # +1
Ситуация, как правило, следующая: показываем очень быстро обновляющуюся таблицу, например биржевые сводки курсов валют, или что-то в этом духе. Данные в таблице обновляются не все одновременно, а что пришло - то и обновили. Чтобы выяснить, нужно ли обновлять строчку / столбец нужно выяснить имеет ли это практический смысл (т.е. изменится ли что либо с точки зрения пользователя), иначе изза тяжеловесного интерфейса будут тормоза. И в этом случае настоящие - а не выдуманные типа тех, которые могут быть вызваны паузами мусорщика.
Что до сравнений - в контексте этой задачи, как правило не нужно принимать во внимание родство между классами, т.как это чаще всего техническая деталь, которая не имеет отношения к задаче - не факт, что все объекты с одним и тем же значением были получены одинаковым способом. Иногда это не возможно по сугубо техническим причинам, например - закрыто наследование от какого-то встроенного класса.
Не смотря на то, что в книжках по Яве этому уделяется глава - этот аспект, как правило создает много головной боли, и тем больше, чем менее тривиальный объект. Что касается разницы с АС, то особенным моментом являются прокси объекты, которые могут управлять перечислением своих свойств (могут их даже создавать и удалять на ходу), могут неадкватно (с точки зрения сравнения) реагировать на вопрос "а есть ли свойство", "а есть ли еще свойства" и "а равно ли свойство чему-то". Ну и кроме того, свойства в АС - могут быть сложными функциями, а ключи могут быть и не строками вовсе, и в таком случае получение списка свойств - это очень заморочливая процедура.
wvxvw 04.04.2013 00:15 # 0
roman-kashitsyn 04.04.2013 14:59 # +4
С чего это вдруг? Если бы наследники должны были возвращать одинаковые с базой выходы для одинаковых входах, смысла в наследовании было бы мало.
Лисков требует отсутствие нарушения семантики и контрактов при наследовании, и с equals тут всё совершенно прекрасно, семантика чётко соблюдена.
3.14159265 04.04.2013 15:02 # +1
Ну кто-то недавно с пеной у рта рассказывал про "неправильное ООП в js", и что там "нет контроля за типизацией" а теперь же наоборот отстаивает нетипизированное, динамическое сравнение.
> переход на HashMap-oriented OOP
Вот-вот. Это ж суть js.
roman-kashitsyn 04.04.2013 15:04 # +2
А в лиспе, похоже, Tuple oriented OOP
wvxvw 04.04.2013 15:32 # 0
Это, кстати может оказаться интересной темов в, например, vObj исчислении. Вполне потянет на статью, если даже не тему для исследовательской работы.
3.14159265 04.04.2013 14:59 # +2
Флешепроблемы. Или же вы просто не умеете их сравнивать.
В общем не буду читать эти простыни, а отплюсую @костоправа.
wvxvw 04.04.2013 15:47 # 0
- вы не пишете на АС, поэтому вам все равно как оно будет, или не будет работать. Ну и ваше мнение не то чтобы совсем высосано из пальца, но опирается на реалии совсем другого языка, которых просто нет в этом контексте.
- костоправ - очень самонадеяный Ява-писатель, который по неопытности набрел на какой-то код, который не понял, но решил, что это плохо, потому что в Яве это можно сделать по-другому.
Что получится врезультате: скорее всего костоправ запилит копию явовских equals, потом будет очень долго воевать с существующей системой, которая в его мирок никак не будет укладываться. А потом, скорее всего бросит это дело / локально пофиксит несколько явных проблем. Потом перейдет в другой отдел и будет с ужасом вспоминать о проделаной работе.
Хуже всех будет тем, кому достанется в поддержку задел оставленный костоправом, на поддержку / переделку.
Случалось много раз.
kostoprav 04.04.2013 15:48 # +2
Будет больше похоже на правду.
wvxvw 04.04.2013 15:53 # 0
kostoprav 04.04.2013 15:55 # +4
wvxvw 04.04.2013 16:06 # 0
Если эту функцию использовали там, где можно было сравнить ссылки - тогда бы ее удаление / замена была бы оптимизацией, а если нет - вероятность того, что вы что-то существенно улучшили бы заменив ее equals стремится к нулю.
Но вот ваши выводы про типизацию: у Явистов как бы и альтернативы никакой нет... любят не любят - в Яве никакой динамической типизации не будет в обозримом будущем. В АС есть разные подходы, и, хоть я и не сторонник, но иногда потеря типизации оправдана. Как аргумент в защиту: это сокращает код. Делает его более понятным убирая технические детали. Позволяет делать код более модульным, совместимым с будущими добавками и изменениями.
Флексовый фреймворк, с другой стороны, написан явистами, которые плохо знали АС, и поэтому он такой какой он есть... с массой неидеоматического кода, заимствоваными бесполезными идеями и условностями.
kostoprav 04.04.2013 16:12 # 0
> Как аргумент в защиту: это сокращает код. Делает его более понятным убирая технические детали. Позволяет делать код более модульным, совместимым с будущими добавками и изменениями.
Особенно потом легко разбираться, что в какой переменной лежит - массив, объект, а может быть вообще число. Бесспорно, легко добавлять новый функционал.
wvxvw 04.04.2013 16:28 # 0
Скала (так же известная как JML),
Питон,
Эрланг,
Камл,
В Лиспе аннотации типов опциональные и их используют только в случае необходимости оптимизации,
Руби,
Смолток (Стронгток - опциональный довесок),
ПХП,
ж. скрипт,
Хекс (опциональное, как в Скале, Камле или Лиспе) - но об этом вы наверное не слышали.
Я так подозреваю, что Перл и Луа - так же устроены, но не пользовался ими никогда.
Этим исчерпываются мои познания, но языков таких много и на них написаны иногда очень большие приложения в сотни тысяч строк.
roman-kashitsyn 04.04.2013 16:32 # +3
wvxvw 04.04.2013 16:43 # 0
roman-kashitsyn 04.04.2013 16:36 # 0
wvxvw 04.04.2013 16:53 # 0
LispGovno 04.04.2013 17:49 # 0
3.14159265 04.04.2013 19:27 # 0
wvxvw 04.04.2013 20:17 # 0
Ключ к разгадке: просто выводим типы, пишем их рядом со словами - и все становится на свои места.
kostoprav 04.04.2013 16:38 # 0
Lua подобно AS поддерживает разные парадигмы типизации.
kostoprav 04.04.2013 16:40 # 0
bot 02.04.2013 21:47 # 0
kyzi007 03.04.2013 13:42 # 0
3.14159265 03.04.2013 16:12 # +1
http://govnokod.ru/12741#comment172084
kyzi007 04.04.2013 15:35 # 0
vistefan 03.04.2013 23:21 # 0
Насколько интуитивен код ?
А, так там вообще compareObjects