Я бачу, що пропоновані відповіді зосереджені на результатах. У статті, поданій нижче, не міститься нічого нового щодо продуктивності, але вона пояснює основні механізми. Також зверніть увагу, що він не фокусується на трьох Collection
Типах, згаданих у питанні, а звертається до всіх Типів System.Collections.Generic
простору імен.
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choose-the-right-collection-class.aspx
Екстракти:
Словник <>
Словник - це, мабуть, найбільш вживаний асоціативний клас контейнера. Словник - це найшвидший клас для асоціативних пошуків / вставок / видалень, оскільки він використовує хеш-таблицю під обкладинками . Оскільки ключі хешовані, тип ключів повинен правильно реалізовувати GetHashCode () та Equals () належним чином, або ви повинні надати зовнішній IEqualityComparer до словника при побудові. Час вставки / видалення / пошуку елементів у словнику амортизується постійним часом - O (1) - це означає, що незалежно від того, наскільки великий стає словник, час, необхідний для пошуку чогось, залишається відносно постійним. Це дуже бажано для високошвидкісних пошуків. Єдиним недоліком є те, що словник за характером використання хеш-таблиці є невпорядкованим, томуВи не можете легко прокрутити елементи у Словнику по порядку .
Сортований словник <>
Сортований словник схожий на Словник у використанні, але дуже різний у реалізації. SortedDictionary використовує бінарне дерево під ковдрою , щоб зберегти деталі в порядку ключа . Як наслідок сортування, тип, який використовується для ключа, повинен правильно реалізовувати IComparable, щоб ключі могли бути правильно відсортовані. Відсортований словник торгує трохи часу пошуку для можливості підтримувати елементи в порядку, отже, час вставлення / видалення / пошуку у відсортованому словнику є логарифмічним - O (журнал n). Взагалі кажучи, з логарифмічним часом ви можете подвоїти розмір колекції, і для пошуку предмета потрібно виконати лише одне додаткове порівняння. Використовуйте Сортований словник, коли ви хочете швидко шукати, але також хочете мати можливість підтримувати колекцію в порядку за ключем.
SortedList <>
SortedList - це інший відсортований асоціативний клас контейнерів у загальних контейнерах. Ще раз SortedList, як і SortedDictionary, використовує ключ для сортування пар ключ-значення . Однак, на відміну від SortedDictionary, елементи у SortedList зберігаються як відсортований масив елементів. Це означає, що вставки та видалення є лінійними - O (n) - оскільки видалення або додавання елемента може включати зміщення всіх елементів вгору або вниз у списку. Однак час пошуку - O (журнал n), оскільки SortedList може використовувати двійковий пошук, щоб знайти будь-який елемент у списку за його ключем. То чому б вам колись захотілося це зробити? Ну, відповідь полягає в тому, що якщо ви збираєтеся завантажувати SortedList заздалегідь, вставки будуть повільнішими, але оскільки індексація масиву відбувається швидше, ніж наступні посилання на об’єкти, пошук виконується незначно швидше, ніж SortedDictionary. Ще раз я б використовував це в ситуаціях, коли ви хочете швидко шукати і хочете підтримувати колекцію в порядку за ключем, і коли вставки та видалення трапляються рідко.
Орієнтовний огляд основних процедур
Відгуки дуже вітаються, оскільки я впевнений, що я не все зрозумів.
- Усі масиви мають розмір
n
.
- Невідсортований масив = .Add / .Remove - O (1), але .Item (i) - O (n).
- Відсортований масив = .Add / .Remove - O (n), але .Item (i) - O (log n).
Словник
Пам'ять
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
Додайте
- Додати
HashArray(n) = Key.GetHash
# O (1)
- Додати
KeyArray(n) = PointerToKey
# O (1)
- Додати
ItemArray(n) = PointerToItem
# O (1)
Видалити
For i = 0 to n
, знайти i
де HashArray(i) = Key.GetHash
# O (журнал n) (відсортований масив)
- Видалити
HashArray(i)
# O (n) (відсортований масив)
- Видалити
KeyArray(i)
# O (1)
- Видалити
ItemArray(i)
# O (1)
Отримати товар
For i = 0 to n
, знайти i
де HashArray(i) = Key.GetHash
# O (журнал n) (відсортований масив)
- Повернення
ItemArray(i)
Петля наскрізь
For i = 0 to n
, повернення ItemArray(i)
Сортований словник
Пам'ять
KeyArray(n) = non-sorted array<pointer>
ItemArray(n) = non-sorted array<pointer>
OrderArray(n) = sorted array<pointer>
Додайте
- Додати
KeyArray(n) = PointerToKey
# O (1)
- Додати
ItemArray(n) = PointerToItem
# O (1)
For i = 0 to n
, знайти i
де KeyArray(i-1) < Key < KeyArray(i)
(використовуючи ICompare
) # O (n)
- Додати
OrderArray(i) = n
# O (n) (відсортований масив)
Видалити
For i = 0 to n
, знайти i
де KeyArray(i).GetHash = Key.GetHash
# O (n)
- Видалити
KeyArray(SortArray(i))
# O (n)
- Видалити
ItemArray(SortArray(i))
# O (n)
- Видалити
OrderArray(i)
# O (n) (відсортований масив)
Отримати товар
For i = 0 to n
, знайти i
де KeyArray(i).GetHash = Key.GetHash
# O (n)
- Повернення
ItemArray(i)
Петля наскрізь
For i = 0 to n
, повернення ItemArray(OrderArray(i))
SortedList
Пам'ять
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
Додайте
For i = 0 to n
, знайти i
де KeyArray(i-1) < Key < KeyArray(i)
(використовуючи ICompare
) # O (log n)
- Додати
KeyArray(i) = PointerToKey
# O (n)
- Додати
ItemArray(i) = PointerToItem
# O (n)
Видалити
For i = 0 to n
, знайти i
де KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Видалити
KeyArray(i)
# O (n)
- Видалити
ItemArray(i)
# O (n)
Отримати товар
For i = 0 to n
, знайти i
де KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Повернення
ItemArray(i)
Петля наскрізь
For i = 0 to n
, повернення ItemArray(i)