Limites práticos de tamanho de uma tabela de hash e dicionário em c #

12

Quais são os limites práticos para o número de itens que um dicionário C # 4 ou Hashtable podem conter e o número total de bytes que essas estruturas podem conter razoavelmente. Trabalharei com um grande número de objetos e quero saber quando essas estruturas começarem a ter problemas.

Como contexto, usarei um sistema de 64 bits com toneladas de memória. Além disso, precisarei encontrar objetos usando algum formulário ou 'chave'. Dadas as demandas de desempenho, esses objetos precisarão residir na memória e muitos terão vida longa.

Sinta-se livre para sugerir outras abordagens / padrões, embora eu precise evitar o uso de bibliotecas de terceiros ou de código aberto. Por motivos de especificação, preciso criar isso usando C # nativo ( ou C ++ \ CLI ).

JoeGeeky
fonte
1
Deve levar apenas uma ou duas horas para simular esse material e medir o desempenho de adição / remoção / pesquisa em diferentes utilizações / cargas. Acredito que o VS2010 ainda fornece esqueleto de teste de desempenho para você. Não importa o que alguém diga aqui, o código que você escreverá terá seu nome, diretamente ou em metadados.
Job

Respostas:

8

Uma coisa a salientar é que o Dictionary não retém o objeto em si (que pode ter uma grande área de memória), mas apenas uma referência ao objeto; portanto, se os objetos forem complexos, isso não terá impacto no tamanho do Dictionary.

Eu coletei vários milhares de itens juntos em um Dicionário na memória e o problema não é o tamanho do Dicionário, mas o tamanho dos próprios objetos na memória. Nesses casos, o próprio dicionário era uma pequena parte da memória envolvida.

Uma coisa a se pensar nos casos de dicionários grandes é configurar e gerenciar manualmente a capacidade do dicionário. Em circunstâncias normais, o .Net gerencia essa multa (na implementação atual, se ficar sem espaço, ela será redimensionada para um número primo que seja pelo menos duas vezes o tamanho atual do Dicionário). No entanto, se você sabe que criará um grande dicionário ou expandirá o dicionário em vez de adivinhar e redimensionar o dicionário para você (o que é relativamente caro), provavelmente é melhor você fazer isso sozinho (certamente com a inicial tamanho e provavelmente o redimensionamento posterior). Isso pode ser feito gerenciando a capacidade do Dicionário se você tiver uma idéia heurística razoável de qual deve ser a capacidade do Dicionário. A Microsoft recomenda isso emMSDN em seus comentários sobre o objeto Dictionary . No entanto, parece haver algum debate sobre o valor real dessa abordagem, embora eu não tenha certeza de quão rigoroso é esse teste e se há outras otimizações que a plataforma .Net implementa quando um dicionário está redimensionando extremamente rapidamente.

Essa é uma pergunta útil sobre estouro de pilha sobre o tamanho do objeto e da memória.

AlexC
fonte
2

Os limites práticos podem ser relativos à máquina em que o software está sendo executado, bem como a quantos objetos você realmente planeja conter nessas estruturas de dados. Como Oded mencionou, int.MaxValue é um número grande, mas 2 bilhões de itens equivalem a um limite prático? Armazenar muitos itens na memória provavelmente não é muito prático.

Bernard
fonte
0

Como a documentação não informa onde estão os dados fisicamente armazenados e não especifica o limite, sugiro que você realize um experimento com o tamanho máximo esperado que você provavelmente terá e anote a memória do sistema antes e depois da alocação de armazenamento.

NoChance
fonte
-1

Recentemente, atualizei o hash-table-shootout do projeto github (aqui: https://github.com/jimbelton/hash-table-shootout ). O mapa não ordenado do gcc padrão possui cerca de 1,8 GBytes de sobrecarga para armazenar objetos de 40 milhões. Isso me parece bastante atroz, mas mesmo o melhor artista em termos de memória, o sparse_hash_map do Google, ocupa 600 Mbytes e você paga uma penalidade de desempenho por usá-lo. Se você deseja velocidade, dentre os algoritmos incluídos, o Glib GHashTable é o mais rápido e possui bom desempenho de memória (sobrecarga de 1,3 Gbytes). Os resultados do benchmark estão publicados aqui: https://jimbelton.wordpress.com/2015/07/01/hash-table-shootout-on-github/

Jim Belton
fonte