Posso ver que as respostas propostas se concentram no desempenho. O artigo fornecido a seguir não fornece nada de novo em relação ao desempenho, mas explica os mecanismos subjacentes. Observe também que ele não se concentra nos três Collection
Tipos mencionados na pergunta, mas aborda todos os Tipos do System.Collections.Generic
namespace.
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
Extrai:
Dicionário <>
O Dicionário é provavelmente a classe de contêiner associativa mais usada. O Dicionário é a classe mais rápida para pesquisas / inserções / exclusões associativas porque usa uma tabela de hash por baixo dos panos . Como as chaves são hash, o tipo de chave deve implementar corretamente GetHashCode () e Equals () ou você deve fornecer um IEqualityComparer externo ao dicionário na construção. O tempo de inserção / exclusão / pesquisa de itens no dicionário é o tempo constante amortizado - O (1) - o que significa que não importa o tamanho do dicionário, o tempo que leva para encontrar algo permanece relativamente constante. Isso é altamente desejável para pesquisas de alta velocidade. A única desvantagem é que o dicionário, por natureza de usar uma tabela hash, não está ordenado, entãovocê não pode percorrer facilmente os itens em um Dicionário em ordem .
SortedDictionary <>
O SortedDictionary é semelhante ao Dicionário no uso, mas muito diferente na implementação. O SortedDictionary usa uma árvore binária nos bastidores para manter os itens em ordem pela chave . Como consequência da classificação, o tipo usado para a chave deve implementar IComparable corretamente para que as chaves possam ser classificadas corretamente. O dicionário classificado troca um pouco do tempo de pesquisa pela capacidade de manter os itens em ordem, portanto, os tempos de inserção / exclusão / pesquisa em um dicionário classificado são logarítmicos - O (log n). De modo geral, com o tempo logarítmico, você pode dobrar o tamanho da coleção e basta fazer uma comparação extra para encontrar o item. Use o SortedDictionary quando quiser pesquisas rápidas, mas também quiser manter a coleção em ordem pela chave.
SortedList <>
O SortedList é a outra classe de contêiner associativa classificada nos contêineres genéricos. Mais uma vez, SortedList, como SortedDictionary, usa uma chave para classificar pares de valores-chave . Ao contrário de SortedDictionary, no entanto, os itens em uma SortedList são armazenados como uma matriz classificada de itens. Isso significa que as inserções e exclusões são lineares - O (n) - porque excluir ou adicionar um item pode envolver o deslocamento de todos os itens para cima ou para baixo na lista. O tempo de pesquisa, entretanto, é O (log n) porque SortedList pode usar uma pesquisa binária para encontrar qualquer item na lista por sua chave. Então, por que você quer fazer isso? Bem, a resposta é que se você for carregar a SortedList antecipadamente, as inserções serão mais lentas, mas como a indexação de array é mais rápida do que seguir links de objetos, as pesquisas são ligeiramente mais rápidas do que SortedDictionary. Mais uma vez, eu usaria isso em situações em que você deseja pesquisas rápidas e deseja manter a coleção em ordem por chave, e onde inserções e exclusões são raras.
Resumo provisório dos procedimentos subjacentes
O feedback é muito bem-vindo, pois tenho certeza de que não acertei tudo.
- Todas as matrizes são de tamanho
n
.
- Matriz não classificada = .Add / .Remove é O (1), mas .Item (i) é O (n).
- Matriz classificada = .Add / .Remove é O (n), mas .Item (i) é O (log n).
Dicionário
Memória
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
Adicionar
- Adicionar
HashArray(n) = Key.GetHash
# O (1)
- Adicionar
KeyArray(n) = PointerToKey
# O (1)
- Adicionar
ItemArray(n) = PointerToItem
# O (1)
Remover
For i = 0 to n
, encontre i
onde HashArray(i) = Key.GetHash
# O (log n) (matriz classificada)
- Remova
HashArray(i)
# O (n) (matriz classificada)
- Remova
KeyArray(i)
# O (1)
- Remova
ItemArray(i)
# O (1)
Obter Item
For i = 0 to n
, encontre i
onde HashArray(i) = Key.GetHash
# O (log n) (matriz classificada)
- Retorna
ItemArray(i)
Loop Through
For i = 0 to n
, Retorna ItemArray(i)
SortedDictionary
Memória
KeyArray(n) = non-sorted array<pointer>
ItemArray(n) = non-sorted array<pointer>
OrderArray(n) = sorted array<pointer>
Adicionar
- Adicionar
KeyArray(n) = PointerToKey
# O (1)
- Adicionar
ItemArray(n) = PointerToItem
# O (1)
For i = 0 to n
, encontre i
onde KeyArray(i-1) < Key < KeyArray(i)
(usando ICompare
) # O (n)
- Adicione
OrderArray(i) = n
# O (n) (matriz classificada)
Remover
For i = 0 to n
, encontre i
onde KeyArray(i).GetHash = Key.GetHash
# O (n)
- Remova
KeyArray(SortArray(i))
# O (n)
- Remova
ItemArray(SortArray(i))
# O (n)
- Remova
OrderArray(i)
# O (n) (matriz classificada)
Obter Item
For i = 0 to n
, encontre i
onde KeyArray(i).GetHash = Key.GetHash
# O (n)
- Retorna
ItemArray(i)
Loop Through
For i = 0 to n
, Retorna ItemArray(OrderArray(i))
SortedList
Memória
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
Adicionar
For i = 0 to n
, encontre i
onde KeyArray(i-1) < Key < KeyArray(i)
(usando ICompare
) # O (log n)
- Adicionar
KeyArray(i) = PointerToKey
# O (n)
- Adicionar
ItemArray(i) = PointerToItem
# O (n)
Remover
For i = 0 to n
, encontre i
onde KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Remova
KeyArray(i)
# O (n)
- Remova
ItemArray(i)
# O (n)
Obter Item
For i = 0 to n
, encontre i
onde KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Retorna
ItemArray(i)
Loop Through
For i = 0 to n
, Retorna ItemArray(i)