Здравствуйте, adontz, Вы писали:
A>Как нетрудно убедиться h1 != h2. А вот с моей точки зрения объекты равны, потому что у обоих поле data = 3, а других полей нет.
Не удивительно: A -- это класс, так что семантика сравнения у него ссылочная. Хочешь генерации хеша на освнове содержимого -- сделай его структурой.
Здравствуйте, Mab, Вы писали:
A>>Как нетрудно убедиться h1 != h2. А вот с моей точки зрения объекты равны, потому что у обоих поле data = 3, а других полей нет. Mab>Не удивительно: A -- это класс, так что семантика сравнения у него ссылочная. Хочешь генерации хеша на освнове содержимого -- сделай его структурой.
Это понятно. Я просто говорю, что реализация по умолчанию это совсем не то что нужно для switch.
Здравствуйте, Mab, Вы писали:
Mab>XmlSerializer не умеет работать с IDictionary. Только непонятно, при чем тут это...? Mab>Возьми BinaryFormatter, он замечательно сериализует твой класс.
Это при том, что Wolfhound прицепился к моей фразе.
Тут как бы вообще другой вопрос и я уже жалею что привёл это непонятую аналогию.
Суть в том, что классы реализующие IDictionary в частности, и коллекции вообще это проблема от которой надо избавляться, а не решать. И дело тут не в подходе (хеш или оператор), а в осмысленности. Вот два массива {1,2,3} и {3,1,2} равны или нет? Причём ответь так, чтобы всех удовлетворило. Очевидно, что ответа нет. Причём его нет и для хешей. А Wolfhound этим почему-то доказывает, что оператор < это плохо
A>public class A
A>{
A> public int data = 3;
A> public A()
A> {
A> }
A>}
A>A a1 = new A();
A>A a2 = new A();
A>int h1 = a1.GetHashCode();
A>int h2 = a2.GetHashCode();
A>
A>Как нетрудно убедиться h1 != h2.
Напоминаю, что исходно речь шла о типах.
... << RSDN@Home 1.2.0 alpha rev. 624 on Windows XP 5.1.2600.131072>>
Здравствуйте, adontz, Вы писали:
WH>>2)Hashtable прекрасно сериализуется. Учи матчасть. A>Я рыдаю. A>Друг, ты хоть с документацией сверяйся, а потом говори, если так не помнишь
Ну рыдай дальше. Только сначала изучи предмет.
hint: в поставку .NET входят 2 сериалайзера один из которых (XmlSerializer) действительно не умеет работать с IDictionary (правда не понятно почему особенно учитывая то что реализовать IXmlSerializable для словаря не составляет проблем).
Но это не отменяет второй вернее основной сериалайзер который использует платформа.
WH>>3)Может ты всетки определишь отношение порядка для StateSet? Или слабо? A>Что значит слабо? Есть инструмент — оператор switch и есть множество классов которые в нём можно использовать. Классы реализующие интерфейс IDictionary в это множество не входят.
А чем они хуже? А! Знаю! Такие объекты практически не возможно запихнуть в ту систему что ты тут позиционируешь как единственно верную. A>Не надо доводить до маразма. И уж точно аргументация "слабо", "не слабо" не привносит в дискуссию элементы интеллекта.
А как с тобой еще разговаривать если ты уперся и твердишь что деревья единственно верный способ на все случаи жизни?
A>Вобщем все аргументы против "operator <" свелись к тому что A>Индусы пишут в "operator <" вызов Sleep(1000); и поэтому он медленный
Это был ответ на то что некие черти напишут плохую хеш функцию. A>Роме слабо реализовать этот оператор для класса StateSet. Правда он в операторе switch представляется с трудом, но это не важно.
А это пример к тому что есть объекты для которых очень сложно задать отношение порядка.
A>Очень интересно, но совершенно не убедительно.
А твои аргументы вобще не выдерживают никакой критики.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, adontz, Вы писали:
A>Суть в том, что классы реализующие IDictionary в частности, и коллекции вообще это проблема от которой надо избавляться, а не решать. И дело тут не в подходе (хеш или оператор), а в осмысленности. Вот два массива {1,2,3} и {3,1,2} равны или нет? Причём ответь так, чтобы всех удовлетворило. Очевидно, что ответа нет. Причём его нет и для хешей. А Wolfhound этим почему-то доказывает, что оператор < это плохо
Ну почемуже сразу избавляться?
Все зависит от задачи. В моем случае равны. Соответственно я написал хеш и сравнение которым порядок до лампочки. Если бы порядок элементов в массиве имел значение то вычисление хеша и сравнение я бы реализовал иначе.
Сходи по моей ссылке и попробуй решить эту задачу без сравнения множеств...
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>А чем они хуже? А! Знаю! Такие объекты практически не возможно запихнуть в ту систему что ты тут позиционируешь как единственно верную.
Я не сказал, что она единственно верная, я даже не говорю что она самая оптимальная, я говорю что в ней нету подводных камней. Ты вообще не те параметры хвалишь.
WH>Это был ответ на то что некие черти напишут плохую хеш функцию.
Плохая не хначит медленная. Плохая значит, что биты значения не независимы (то есть их фактически в хеш-таблице будут незаполняемые дырки) либо не равновероятны (что опять таки приводит в незаполняемым дыркам). Характеристика плохой в контексте моего высказывания не имела никакого отношения к скорости работы хеш-функции.
A>>Роме слабо реализовать этот оператор для класса StateSet. Правда он в операторе switch представляется с трудом, но это не важно. WH>А это пример к тому что есть объекты для которых очень сложно задать отношение порядка.
На самом деле для любой упорядоченной коллекции отношения порядка задаётся очень просто. Беда в том, что IDictionary это не упорядоченная коллекция.
Здравствуйте, adontz, Вы писали:
A>Ты внимательно почитай о чём речь. Мы говорили не о коллекциях, а об операторе switch по любым объектам. Чтобы это было реализовано не абы как, а качественно, из констант после case надо построить двочное дерево поиска. А для этого надо сами эти константы упорядочить. Иначе switch ничем не будет отличаться от последовательности if, а нам такой switch не нужен!
Ты вроде бы раньше разбирался в том, что такое хэш-таблица и как она работает. Странно слышать от тебя такие слова.
Общая идея тут такова. Код вроде этого:
void TestMethod(object obj)
{
switch (obj)
{
case new Class1(someState1): SomeBehavior1() break;
case new Class1(someState2): SomeBehavior2() break;
case new Class1(someState3): SomeBehavior3() break;
case new Class2(someState1): SomeBehavior4() break;
default: SomeBehavior5() break;
}
}
Переписывается компилятором следующим образом:
static Dictionary<object, int> _unic_comiler_name1;
void TestMethod(object obj)
{
if (_unic_comiler_name1 == null)
{
// Инициализация хэш-таблицы используемой для реализации switch-а
_unic_comiler_name1 = Dictionary<object, int>()
_unic_comiler_name1.Add(new Class1(someState1), 1);
_unic_comiler_name1.Add(new Class1(someState2), 2);
_unic_comiler_name1.Add(new Class1(someState3), 3);
_unic_comiler_name1.Add(new Class2(someState1), 4);
}
// Для подобных свитчей (с последовательными индексами)
// компилятор генерирует оптимальный код (O(1)).int index;
// Если ключа не будет в хэш-таблице, то будет возвращено значение "0".
_unic_comiler_name1.TryGetValue(obj, out index)
switch (index)
{
case 1: SomeBehavior1() break;
case 2: SomeBehavior2() break;
case 3: SomeBehavior3() break;
case 4: SomeBehavior4() break;
default: SomeBehavior5() break;
}
}
Хэш-таблица (Dictionary<object, int>) обеспечивает поиск порядка O(1), т.е. за константное время. Ну, а дальше уже дело техники. Единственно, нужно реализовать в объектах корректное сравнение и корректный рассчет хэш-кода.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Ваша дискуссия сильно затянулась. Скожу только, что ты действительно как-то странно относишся к хэш-таблицам. Но это общая проблема многих С++-ников. В STL ведь действительно серьезные проблемы с этим делом. Ну, да ладно.
Так вот хэш-таблице доказали свое приемущество на практике, а не только в теории. Конечно выражденные случаи случаются, но это большая редкость. Да и не составляет проблем отловить эти случаи с помощью банального профайлера.
Собственно реализация switch-а по строкам в C# уже использует хэширование и хэш-таблицы. Можешь декомпилировать вот такой код:
using System;
class Program
{
static void Main()
{
Test("A");
Test("X");
}
static void Test(string str)
{
switch (str)
{
case"A": Console.WriteLine("str содержит 'A'"); break;
case"B": Console.WriteLine("str содержит 'B'"); break;
case"C": Console.WriteLine("str содержит 'C'"); break;
case"D": Console.WriteLine("str содержит 'D'"); break;
case"E": Console.WriteLine("str содержит 'E'"); break;
case"F": Console.WriteLine("str содержит 'F'"); break;
default: Console.WriteLine("str содержит что-то иное"); break;
}
}
}
и убедиться, что компилятор C# сгеренировал код на основе хэш таблицы. Вот, например, что он сгенерировал в моем случае:
Здравствуйте, Mab, Вы писали:
A>>Как нетрудно убедиться h1 != h2. А вот с моей точки зрения объекты равны, потому что у обоих поле data = 3, а других полей нет. Mab>Не удивительно: A -- это класс, так что семантика сравнения у него ссылочная. Хочешь генерации хеша на освнове содержимого -- сделай его структурой.
Или переопредели поведение методов GetHashCode() и Equal().
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, adontz, Вы писали:
A>Это понятно. Я просто говорю, что реализация по умолчанию это совсем не то что нужно для switch.
И ошибашся. Все зависит от того что ты хочешь получить. Если тебе достаточно сравения экземпляров, то реализация по уполчанию подойдет. Если же ты хочешь сравнивать объекты семантически, то ты просто обязан переопределить поведение GetHashCode() и Equal().
Это общее правило, и switch тут ничего ровным счетом не меняет. Ты точно так же сможешь сравнить объекты по "==" с помощью Equal() если тебе нужно семантическое сравнение, а ты не переопределил GetHashCode() и Equal().
ЗЫ
В общем, это уже похоже на вреднечинье. Тебе столько людей пытаются обяснить детские прописные истины, а ты упирашся и отказывашся признавать очевидное.
Думаю, что обсуждать что-то дальше не имеет смысла. Ты внушил себе какие-то странные догмы и никто кроме тебя самого не разрушит их. Так что или продолжай верить в догмы, или попытайся осмыслить все сказанное и разрушить их.
Заметь, создатели компиятора того же C# беспрепятсвенно используют хэш-таблицы при реализации строковых свитчей.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Заметь, создатели компиятора того же C# беспрепятсвенно используют хэш-таблицы при реализации строковых свитчей.
Влад, я не против хеш-таблиц, я прекрастно понимаю, все их преимущества! Но хеш-таблицам нужны хеш-функции, а писать их будет кто-попало. И я думаю, что от этого проблем будет больше чем пользы.
Здравствуйте, VladD2, Вы писали:
VD>Ваша дискуссия сильно затянулась. Скожу только, что ты действительно как-то странно относишся к хэш-таблицам. Но это общая проблема многих С++-ников. В STL ведь действительно серьезные проблемы с этим делом. Ну, да ладно.
Си++ тут ни при чём и к хеш-таблицам я отношусь замечательно.
VD>Так вот хэш-таблице доказали свое приемущество на практике, а не только в теории. Конечно выражденные случаи случаются, но это большая редкость. Да и не составляет проблем отловить эти случаи с помощью банального профайлера.
В том-то всё и дело, что проблема. Даже если ты спустишься на уровень IL, то тормозить у тебя будет Dictionary<string, int>.TryGetValue, причём совершенно не ясно почему.
VD>Собственно реализация switch-а по строкам в C# уже использует хэширование и хэш-таблицы. Можешь декомпилировать вот такой код:
Влад, GetHashCode для строк и GetHashCode для произвольного класса написанного Васей Пупкиным ну очень различаются по качеству.
Здравствуйте, adontz, Вы писали:
A>Влад, я не против хеш-таблиц, я прекрастно понимаю, все их преимущества! Но хеш-таблицам нужны хеш-функции, а писать их будет кто-попало. И я думаю, что от этого проблем будет больше чем пользы.
Любые функции может писать кто попало. При этом результат может быть печальным. И какие из этого можно сделать выводы?
Прекрати упираться на ровном месте. Тебе же все уже обяснили. Семантика эквивалентности более широко применеима нежели сравнения на больше меньше. Есть типы которые просто нельзя сравнивать на болше меньше. Например, сравни на болше меньше два типа, или две персоны. В общем, случае это не имеет смысла.
Скорость работы хэш-таблиц обычно выше чем бинарного поиска.
Так зачем делать неполноценное, более медленное решение? Только из-за того, что кто-то не верит в хэширование? Может проще этому кому-то разобраться с эданным процессом?
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, adontz, Вы писали:
A>Си++ тут ни при чём и к хеш-таблицам я отношусь замечательно.
Все же причем. Я уже не одного С++-ника встречал который борится с хэш-таблицами. Хотя конечно это только мой опыт.
VD>>Так вот хэш-таблице доказали свое приемущество на практике, а не только в теории. Конечно выражденные случаи случаются, но это большая редкость. Да и не составляет проблем отловить эти случаи с помощью банального профайлера.
A>В том-то всё и дело, что проблема.
Да? Приведи, плиз, примеры этого. Тольк из практики, а не из пальца.
A> Даже если ты спустишься на уровень IL, то тормозить у тебя будет Dictionary<string, int>.TryGetValue, причём совершенно не ясно почему.
Да не будет он тормозить. По крайней мере в 99% случаев. И проблема — это не реализации свитча, а качества подбора хэш-функции.
VD>>Собственно реализация switch-а по строкам в C# уже использует хэширование и хэш-таблицы. Можешь декомпилировать вот такой код:
A>Влад, GetHashCode для строк и GetHashCode для произвольного класса написанного Васей Пупкиным ну очень различаются по качеству.
И в какую сторону? Короче, не высасывай пробшем из пальца. А то это выглядит так же смешно, как рассказы о естественности select-а в конце SQL-запроса.
Тот кто будет использовать объекты в switch-е должен понимать, что делает. И если он что-то сделает не так, то в превую очередь он получит неверное поведение. Ну, а далее пусть разбирается.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, adontz, Вы писали:
A>Ага, щас. Был и ещё какой. Несколько дней переписывал хеш-функцию пока вышло что-то приличное. Это у тебя всё как-то гладко, а в жизни оно не так.
Несколько дней на хэш-функцию? Ну, ты крут, однако!
Открою тебе сикрет. В дотнете практически вообще не приходится писать хэш-функции. Ну, разве что для составных объектов которые просто складывают хэшы подобъектов по "^". Я вот за все время написал штуки 3 хэш-функции из них только одну по реальным данным. Остальные "^".
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.