Здесь много хороших идей, но разбросанных, поэтому я попытаюсь создать ответ, который излагает его лучше, даже при том, что проблема была решена.
Во-первых, словарь имеетнет гарантированного заказа, поэтому вы используете его только для быстрого поиска ключа и поиска соответствующего значения, или вы перечисляете все пары ключ-значение, не заботясь о порядке.
Если вы хотите заказать, выиспользуйте OrderedDictionary, но компромисс заключается в том, что поиск выполняется медленнее, поэтому, если вам не нужен порядок, не спрашивайте его.
В словарях (и HashMap в Java) используется хеширование.Это время O (1) независимо от размера вашего стола.Упорядоченные словари обычно используют некое сбалансированное дерево O (log2 (n)), поэтому по мере роста ваших данных доступ замедляется.Для сравнения, для 1 миллиона элементов это порядка 2 ^ 20, поэтому вам нужно сделать порядка 20 поисков для дерева, но 1 для хэш-карты.Это намного быстрее.
Хеширование детерминировано.Недетерминизм означает, что когда вы хешируете (5) в первый раз, а вы хешируете (5) в следующий раз, вы получаете другое место.Это было бы совершенно бесполезно.
То, что люди хотели сказать, это то, что если вы добавляете что-то в словарь, порядок усложняется и может изменяться каждый раз, когда вы добавляете (или потенциально удаляете) элемент.Например, представьте, что в хэш-таблице содержится 500 тыс. Элементов, а у вас есть 400 тыс. Значений.Когда вы добавляете еще один, вы достигаете критического порога, потому что для эффективности ему требуется около 20% пустого пространства, поэтому он выделяет большую таблицу (скажем, 1 миллион записей) и повторно хэширует все значения.Теперь все они находятся в разных местах, чем были раньше.
Если вы создадите один и тот же словарь дважды (внимательно прочитайте мое утверждение, ТО ЖЕ ВРЕМЯ), вы получите тот же порядок.Но, как правильно говорит Джон, не рассчитывайте на это.Слишком много вещей могут сделать его не таким, даже изначально выделенный размер.
Это поднимает превосходную точку.Это очень, очень дорого, чтобы изменить размер хеш-карты.Это означает, что вы должны выделить большую таблицу и заново вставить каждую пару ключ-значение.Так что стоит выделить в 10 раз больше памяти, чем нужно, чтобы не происходило даже одного увеличения.Знайте свой размер hashmap и достаточно предварительно распределяйте, если это вообще возможно, это огромный выигрыш в производительности.И если у вас плохая реализация, которая не изменяет размер, это может быть катастрофой, если вы выберете слишком маленький размер.
Теперь, о чем Джон спорил со мной в моем комментарии в своем ответе, было то, что если выдобавить объекты в словарь в двух разных запусках, вы получите два разных порядка.Да, но это не ошибка словаря.
Когда вы говорите:
new Foo();
, вы создаете новый объект в новом месте в памяти.
Если вы используетезначение Foo в качестве ключа в словаре, без какой-либо другой информации, единственное, что они могут сделать, это использовать адрес объекта в качестве ключа.
Это означает, что
var f1 = new Foo(1);
var f2 = new Foo(1);
f1 и f2 - это не один и тот же объект, даже если они имеют одинаковые значения.
Поэтому, если вы поместите их в словари:
var test = new Dictionary<Foo, string>();
test.Add(f1, "zero");
не ожидайте, что это будеттакой же как:
var test = new Dictionary<Foo, string>();
test.Add(f2, "zero");
, даже если f1 и f2 имеют одинаковые значения.Это не имеет ничего общего с детерминированным поведением словаря.
Хеширование - это потрясающая тема в области компьютерных наук, мой любимый способ преподавания в структурах данных.конец книги о красно-черных деревьях и хэшировании У этого парня по имени Боб есть отличный сайт о хэшировании и оптимальных хешах: http://burtleburtle.net/bob