Я вижу, что предлагаемые ответы сосредоточены на производительности. В статье, представленной ниже, нет ничего нового в отношении производительности, но в ней объясняются основные механизмы. Также обратите внимание, что он не фокусируется на трех Collection
типах, упомянутых в вопросе, а обращается ко всем типам System.Collections.Generic
пространства имен.
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
Выписки:
Словарь <>
Словарь, вероятно, является наиболее часто используемым ассоциативным контейнерным классом. Словарь - это самый быстрый класс для ассоциативного поиска / вставки / удаления, потому что он использует хеш-таблицу под обложками . Поскольку ключи хешированы, тип ключа должен правильно реализовывать GetHashCode () и Equals () соответствующим образом, или вы должны предоставить внешний IEqualityComparer для словаря при построении. Время вставки / удаления / поиска элементов в словаре амортизируется постоянным временем - O (1) - это означает, что независимо от того, насколько велик словарь, время, необходимое для поиска чего-либо, остается относительно постоянным. Это очень желательно для высокоскоростного поиска. Единственным недостатком является то, что словарь по своей природе использования хэш-таблицы неупорядочен, поэтомувы не можете легко перемещаться по элементам в Словаре по порядку .
Сортированный словарь <>
SortedDictionary похож на Dictionary по использованию, но сильно отличается по реализации. SortedDictionary использует бинарное дерево под одеялом , чтобы сохранить детали в порядке ключа . Как следствие сортировки, тип, используемый для ключа, должен правильно реализовывать IComparable, чтобы ключи могли быть правильно отсортированы. Сортированный словарь использует немного времени поиска для возможности поддерживать элементы в порядке, поэтому время вставки / удаления / поиска в отсортированном словаре является логарифмическим - O (log n). Вообще говоря, используя логарифмическое время, вы можете удвоить размер коллекции, и для поиска элемента требуется только одно дополнительное сравнение. Используйте SortedDictionary, если вам нужен быстрый поиск, но вы также хотите поддерживать коллекцию в порядке по ключу.
SortedList <>
SortedList - это еще один класс сортированных ассоциативных контейнеров в общих контейнерах. И снова SortedList, как и SortedDictionary, использует ключ для сортировки пар ключ-значение . Однако, в отличие от SortedDictionary, элементы в SortedList хранятся как отсортированный массив элементов.. Это означает, что вставки и удаления являются линейными - O (n) - потому что удаление или добавление элемента может привести к перемещению всех элементов вверх или вниз в списке. Однако время поиска равно O (log 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 (log n) (отсортированный массив)
- Удалить
HashArray(i)
# O (n) (отсортированный массив)
- Удалить
KeyArray(i)
# O (1)
- Удалить
ItemArray(i)
# O (1)
Получить предмет
For i = 0 to n
, найти i
где HashArray(i) = Key.GetHash
# O (log n) (отсортированный массив)
- Возвращение
ItemArray(i)
Переберите
For i = 0 to n
, возвращение ItemArray(i)
SortedDictionary
объем памяти
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)