Як вибрати функціональну структуру словника даних?


10

Я прочитав трохи про такі структури даних:

  • Ідеальний хеш Багвелла
  • Динамічні хеш-таблиці Larson
  • Червоно-чорні дерева
  • Патріція дерева

... і я впевнений, що там багато інших. Я дуже мало бачив на шляху того, що кожному краще підходить, або чому я б обрала одне над іншим. Отже, ось кілька питань у цьому напрямку:

  1. Про які функціональні структури даних словника важливо знати?
  2. Які плюси і мінуси цих підходів?
  3. Коли має сенс використовувати більш імперативну структуру даних?

Числа 2 і 3, хоча й більш важливі. :-)



Це запитання (крім пункту з номером 3) має відчуття [великий список].
Каве

2
було б корисно дізнатися, чи стосується вищезазначеного питання, яке стосується ваших проблем, а якщо ні, то чому б ні?
Суреш Венкат

@Suresh - це відповіді №1, але важливішими були 2 та 3. Я в основному шукаю огляд великих зображень, щоб визначити, які з них варто вивчити більш глибоко.
Джейсон

2
добре. тож, можливо, варто відредагувати це питання тоді.
Суреш Венкат

Відповіді:


16

Я не можу реально відповісти на №2, не загубившись (є занадто багато розмірів, за якими можна порівняти ці структури), але для №3 відповідь досить проста.

Використовуйте імперативну структуру даних, якщо: (a) немає абсолютно ніякого псевдоніму, або (b) вам дійсно потрібно використовувати псевдонім для ефективного мовлення.

Якщо взагалі немає згладжування вашої структури даних, ви не скористаєтесь тим, що функціональні структури даних є стійкими. Тож немає ніяких причин платити за їх вартість. На цю пораду є два застереження. По-перше, ви можете віддати перевагу простоті реалізації функціональної структури даних: реалізація видалення для функціонального червоно-чорного дерева змусить вас проклинати, але реалізація видалення в імперативному червоно-чорному дереві з батьківськими вказівниками залишить вас задуматися про самогубство. По-друге, призначення може бути дорожчим, ніж ви очікуєте на мові gc'd, оскільки записи можуть перенести структури даних з молодого покоління. У нас дійсно немає хорошої теорії кеш-ефектів і gc, тому у вас немає іншого вибору, як робити бенчмаркінг.

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

Якщо ви або не хочете міркувати про згладжування та право власності на об’єкти, або якщо вам потрібні кілька версій однієї структури даних (скажімо, скажімо, як нова, так і стара версія), просто використовуйте функціональну структуру даних.

Місце, де я знаходжусь за цією порадою, найважче - з графічними алгоритмами. Існує безліч дійсно елегантних імперативних алгоритмів графіків, але часто буває так (скажімо, під час написання компіляторів), що ви також хочете наполегливості. Люди, як правило, намагаються розділити різницю і використовують крутий імперативний алгоритм, але намагаються перетворити версію на сторону, щоб отримати стійкість. Це, як правило, досить жахливо, багато помилок і схильне до втрати ефективності імперативного алгоритму.


2
що в цьому контексті буває?
Суреш Венкат

6
Псевдонім - це коли у вас є кілька посилань на один і той же фрагмент даних. Якщо ці дані є змінними, то міркування про програму, яка їх використовує, повинні явно враховувати всі інші підпрограми, які можуть отримувати доступ та змінювати їх. Якщо цей фрагмент даних є незмінним, то ви можете міркувати локально про програму, яка ним користується, ігноруючи псевдонім, оскільки ви знаєте, що ніхто, хто може отримати доступ до даних, не може їх змінити.
Ніл Крішнасвамі

"але реалізація видалення в імперативному червоно-чорному дереві з батьківськими вказівниками залишить вас замислитись про самогубство". Загальний випадок видалення зводиться до delete-min стандартним трюком, а сам delete-min дуже простий для дерев LLRB. Не потрібні батьківські вказівники.
Per Vognsen

1
"Це, як правило, досить жахливо, багато помилок і схильне втрачати перевагу ефективності імперативного алгоритму." Документ Нормана Рамзі про використання блискавок для керування графіками потоку в оптимізаційному компіляторі дає приклад переконливого компромісу. Ви фактично маєте локальну купу для підтримки простої та ефективної перемотування посилань між базовими блоками в CFG, але маніпулювання вмістом основних блоків є функціональним (або напівфункціональним, залежно від вашого філософського погляду на блискавки).
Per Vognsen

1

Про які функціональні структури даних словника важливо знати?

Бінарні дерева з високою збалансованістю по висоті та спроби їх - хороший всебічний компроміс. Також:

  • Патріція дерева.
  • Хеш намагається.

Які плюси і мінуси цих підходів?

Бінарні дерева з збалансованою висотою і спроби їх - хороший всебічний компроміс для атомних ключів. Спроби однакові для клавіш, які є послідовностями, наприклад, рядкові клавіші.

Дерева Патріції можуть бути в кілька разів швидшими, але дозволяють лише цілі клавіші.

Спроби хешу можуть бути в кілька разів швидшими, ніж врівноважені двійкові дерева, особливо якщо хешування дешевше порівняння і поліморфізм має накладні витрати (наприклад, рядки в .NET), а записування покажчиків у купу швидко (наприклад, віртуальних машин, таких як JVM та CLR, які були оптимізовано для імперативних мов, а не функціональних мов). Хеш-спроби також дозволяють використовувати внутрішню мутацію як оптимізацію.

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

Так само пальчикові дерева не набагато кращі на практиці.

Коли має сенс використовувати більш імперативну структуру даних?

Коли ваш словник заповнюється один раз, а потім використовується лише для пошуку, тобто заморожений.

Коли вам потрібна продуктивність (пристойна хеш-таблиця на зразок .NET, Dictionaryяк правило, на 10-40 × швидша, ніж будь-який загальний суто функціональний словник).

Коли вам потрібен слабкий словник, оскільки не відомий суто функціональний слабкий словник.

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