Словник .NET HashTable Vs - Чи може словник бути таким же швидким?


276

Я намагаюся розібратися, коли і навіщо використовувати Словник або HashTable. Я трохи пошукав тут і знайшов людей, які розмовляють про загальні переваги словника, з яким я повністю погоджуюся, що призводить до переваги боксу та розблокування для невеликого підвищення продуктивності.

Але я також прочитав Словник не завжди повертає об'єкти в тому порядку, в який вони вставлені. Куди як HashTable буде. Як я розумію, це призводить до того, що HashTable в деяких ситуаціях набагато швидший.

Моє запитання справді, якими можуть бути такі ситуації? Чи я просто помиляюся у своїх припущеннях вище? Які ситуації ви можете використовувати для вибору однієї над іншою (так, остання є дещо неоднозначною).


5
Я не хочу цього підкріплювати, але твоя карма - 7 777, і я не хочу бути тим, хто зіпсував це тобі.
КапітанМарвель

Відповіді:


298

System.Collections.Generic.Dictionary<TKey, TValue>і System.Collections.Hashtableкласи підтримують внутрішньо структуру даних хеш-таблиці. Жоден з них не гарантує збереження порядку товарів.

Залишаючи проблеми боксу / розблокування, осторонь у більшості випадків вони повинні мати дуже схожі показники.

Основна структурна відмінність між ними є те , що Dictionaryзалежить від ланцюжка (збереження списку елементів для кожного хешу - таблицю відра) для вирішення колізій в той час як Hashtableвикористання Rehashing для вирішення конфліктів (коли відбувається зіткнення, намагається інший хеш - функція для відображення ключа в відро) .

Користуватися Hashtableкласом мало, якщо ви орієнтуєтесь на .NET Framework 2.0+. Це ефективно застаріло Dictionary<TKey, TValue>.


21
@ Jon- Зв'язування ланцюга та повторне повторне обговорення обговорюється тут- msdn.microsoft.com/en-us/library/ms379571(VS.80).aspx
RichardOD

Дякую обом. Щойно знайшов цю сторінку, коли її розмістив Річард ... Збирався запитати про Chaining, але сайт MSDN насправді корисний!
Джон

6
@Mehrdad - Що мені незрозуміло в тому, як вирішуються зіткнення, це так: якщо декілька клавіш можуть призвести до одного і того ж хешу, то як ви гарантуєте, що ви отримаєте потрібне значення при пошуку, тобто як функція знає, до якого елемента слід звернути увагу повернути? У msdn.microsoft.com/en-us/library/ms379571%28VS.80%29.aspx сказано: "Замість того, щоб докори в разі зіткнення, як це робиться з класом Hashtable, Словник просто ланцюг будь-яких зіткнень. до списку відра. " Чи означає це, що при використанні словника зіткнення - це не те, про що розробник має турбуватися?
Howiecamp

6
@Howiecamp: Це насправді не сильно відрізняється від Hashtable. Таблиці хешу зберігають 3 фрагменти інформації у записі: хеш ключа, сам ключ та значення. Для елементів, що мають рівний хеш, потрібно буде пройти список, щоб знайти елемент з рівним ключем і повернути його значення. Це в значній мірі справедливо і для Hashtable. Як Dictionaryзвичайний розробник , вам не потрібно про це турбуватися.
Мехрдад Афшарі

@Mehrdad Просто для того, щоб було зрозуміло, і об'єкти Hashtable і Dictionary зберігають сам ключ, і обидва також приховують зіткнення від розробника?
Howiecamp

111

Я думаю, це зараз для тебе нічого не означає. Але лише для довідки для людей, які зупиняються

Тест на ефективність - SortedList vs. SortedDictionary vs. Словник проти Hashtable

Виділення пам'яті:

Тест продуктивності використання пам'яті

Час, що використовується для вставки:

Час, що використовується для вставки

Час пошуку предмета:

Час пошуку предмета


Дуже цікаво, що відсортований список має Швидший пошук, ніж хештейн. Я думав, що хештел - це O (1) проти відсортованого списку O (logn). Мабуть, хештейн смокче. Я ніколи його не використовую.
Джон Генкель

@JohnHenckel ні, відсортований список має повільніший пошук. Більший коефіцієнт продуктивності означає кращу продуктивність і краще використання пам'яті. Отже, відсортований список має найкраще використання пам’яті відповідно до графіків, але він затримується в інших областях, таких як вставка та пошук.
C0DEF52

31

Відмінності між Hashtable і словником

Словник:

  • Словник повертає помилку, якщо ми спробуємо знайти ключ, який не існує.
  • Словник швидше, ніж Hashtable, тому що немає боксу та розпакування.
  • Словник - це загальний тип, який означає, що ми можемо використовувати його з будь-яким типом даних.

Hashtable:

  • Хештел повертає нуль, якщо ми спробуємо знайти ключ, який не існує.
  • Hashtable повільніше, ніж словник, оскільки він вимагає боксу та розпакування.
  • Хешбел не є родовим типом,

24

Ще одна важлива відмінність полягає в тому, що тип Hashtable підтримує безліч блокуючих читачів і одночасного запису одночасно, а словник цього не робить.


8
Паралельний словник підтримуватиме (.Net 4.0)
Тамільмаран

1
Я не впевнений, чи розумію цю відповідь. Дивлячись сюди msdn.microsoft.com/en-us/library/…, там написано: "Для підтримки декількох авторів усі операції на Hashtable потрібно виконувати через обгортку, повернуту методом синхронізації, за умови, що немає потоків, що читають об'єкт Hashtable. " Це, мабуть, робить функцію "безлічі замкнених безлічі" досить марною, тож ми повертаємося до того, щоб заблокувати весь доступ до Hashtable, як і у словнику.
RenniePet

16

Стаття MSDN: " Dictionary<TKey, TValue>Клас має таку ж функціональність, що і Hashtableклас. А Dictionary<TKey, TValue> конкретного типу (крім Object) має кращі показники, ніж Hashtableдля типів значень, тому що елементи типу Hashtableє, Objectа отже, бокс та розпакування зазвичай виникають при зберіганні або отримання типу значення ".

Посилання: http://msdn.microsoft.com/en-us/library/4yh14awz(v=vs.90).aspx


11

Обидва фактично одного класу (ви можете подивитися на розбирання). HashTable був створений першим раніше. Net мав загальну інформацію. Однак словник є загальним класом і дає ваші переваги введення тексту. Я ніколи б не використовував HashTable, оскільки словник вам нічого не коштує.


8

Ще одна важлива відмінність полягає Hashtableв безпеці ниток. Hashtableмає вбудовану безпеку нитки для читання / одноразового запису (MR / SW), що Hashtableдозволяє ОДНІЙ автору спільно з декількома читачами без блокування. У разі Dictionaryвідсутності безпеки потоку, якщо вам потрібна безпека нитки, ви повинні здійснити власну синхронізацію.

Детальніше:

Hashtable, забезпечте деяку безпеку потоків через властивість Synchronized, яка повертає захисну нитку обертку навколо колекції. Обгортка працює, блокуючи всю колекцію під час кожного додавання або видалення. Тому кожен потік, який намагається отримати доступ до колекції, повинен дочекатися своєї черги, щоб зняти один замок. Це не масштабується і може призвести до значної погіршення продуктивності для великих колекцій. Також конструкція не повністю захищена від перегонів.

Класи колекції Framework 2.0 подобається List<T>, Dictionary<TKey, TValue>і т.д. не забезпечують синхронізацію потоків; код користувача повинен забезпечувати всю синхронізацію, коли елементи додаються або видаляються на декількох потоках одночасно. Якщо вам потрібна безпека типу, а також безпека потоку, використовуйте паралельні класи колекцій у .NET Framework. Подальше читання тут.


3

Словники мають перевагу в тому, що вони є родовим типом, що робить його безпечним та трохи швидшим через відсутність потреби в боксі. Наступна таблиця порівняння (побудована за допомогою відповідей, знайдених у подібному запитанні про питання SO ) ілюструє деякі інші причини, що підтримують словники над хеш-таблицями (або навпаки).


1

Якщо ви переймаєтесь читанням, яке завжди поверне об'єкти у тому порядку, який вони вставлені у словник, ви можете ознайомитись

OrdersDictionary - значення можна отримати за допомогою цілого індексу (за порядком додавання елементів) SortedDictionary - елементи автоматично сортуються


0

Словник швидше, ніж хештелінг, оскільки словник - це загальний сильний тип. Хештеб повільніше, оскільки він приймає об'єкт як тип даних, що призводить до боксу та розпакування.


2
phase9studios.com/post/2008/01/08/DictionaryVSHashTable.aspx plz прочитайте коментарі під статтею
Arvand

4
@Arvand Посилання зламане - домен для продажу.
RenniePet
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.