2009-05-17 7 views
6

Comment les performances de lecture/ajout de valeurs de/à Dictionary (Of String, SomeReferenceType) dépendent-elles du nombre d'enregistrements déjà entrés? Je veux dire, le temps augmente-t-il en tant que O (1), O (log n), O (n) quand n devient grand, ou d'une autre manière?Performances du dictionnaire (Of String, SomeReferenceType) dans VB.NET

Dim index As New Dictionary(Of String, SomeReferenceType) 

' N entries added in a loop 
' ... 

Dim id As Integer = 123456789 ' 9-digit number 
Dim key As String = id.ToString() 
Dim value As New SomeReferenceType 

index(key) = value ' Need to estimate this 
value = index.TryGetValue(key) ' and this operations depending on N (for large N) 

De plus, que se passe-t-il en cas de manque de mémoire? Devrions-nous définir la capacité du dictionnaire avant d'entrer des éléments pour éviter de le copier au cas où il n'y aurait pas assez d'espace mémoire? Combien de temps dure cette opération (copier le dictionnaire à un nouvel endroit si nécessaire) en fonction de N?

Répondre

6

Les performances d'obtention d'un article à partir d'un Dictionary sont très peu affectées par le nombre d'articles. Les éléments sont divisés en compartiments correspondant à leur code de hachage, de sorte qu'il n'y a généralement qu'un seul ou très peu d'éléments dans chaque compartiment. L'opération est proche d'une opération O (1). L'ajout d'éléments est également proche d'une opération O (1). Si la capacité doit être augmentée, vous obtiendrez un coup de performance, mais en moyenne, c'est très petit. Comme la capacité double à chaque fois, la quantité de données déplacées lors de l'augmentation de la capacité n'est vraiment pas énorme. Les données sont en moyenne déplacées 1,3 fois plus, donc le travail supplémentaire moyen pour chaque ajout revient à déplacer environ 16 octets.

Si vous connaissez la taille que le Dictionary obtiendra, ou si vous avez juste une estimation décente, vous devriez l'utiliser lorsque vous le créez, pour réduire ou éliminer le besoin d'augmenter la capacité.

+0

Merci beaucoup, c'est ce que je demandais. Comment avez-vous obtenu ceci: "Les données sont en moyenne déplacées 1,3 fois plus, donc le travail supplémentaire moyen pour chaque ajout revient à déplacer environ 16 octets."? De plus, comme je l'ai entendu, il y a un problème de capacité. Quelque chose comme la capacité devrait être un nombre premier ... – Roma

+0

Eh bien, le calcul exact a été fait pour une liste, mais un dictionnaire se développe d'une manière similaire. La capacité d'une liste double, donc elle augmente à 32, 64, 128, 256 et ainsi de suite. Quand il a grandi à N, il a au total N éléments copiés, et si en moyenne la moitié de la dernière capacité allouée est utilisée, N est 1,3 fois la taille actuelle. Un dictionnaire sur un système 32 bits utilise 12 octets par élément dans ses tableaux internes, ce qui fait que 1,3 fois 15,6 octets. – Guffa

+0

La capacité d'un dictionnaire est un nombre premier, mais ce n'est rien que vous devez penser, le dictionnaire prend soin de cela par lui-même. – Guffa

2

Dictionary est implémenté avec Hastables - O (1).

SortedDictionary est mis en oeuvre avec des arbres binaires (rouge/noir) - Ainsi O (log n)

SortedList est implémenté avec des listes + binaires de recherche - Ainsi O (n)

Tous les dictionnaires augmenter leur taille automatiquement (performance est O (n) ici mais cela n'arrive pas souvent car la taille est précalculée intelligemment, donc la performance approximative est O (1) de toute façon - Voir this)

Il suffit de les parcourir et de regarder dans la documentation de Microsoft.

+0

"Le dictionnaire est implémenté avec Hastables - Donc O (1)" - en fait, il ne peut pas être constant, il devrait augmenter La taille double chaque fois que nécessaire, donc il y aura plusieurs copies. C'est intéressant combien la copie prend. Comme je l'ai entendu, dans .NET c'est plutôt rapide ... – Roma

+0

Pour être explicite sur un point: il n'y a pas de méthode simple pour définir la capacité maximale d'un dictionnaire. Le paramètre de capacité définit la capacité initiale, il est libre de croître à partir de là. –

+1

Bien sûr, il va copier. Ce n'est pas une contradiction - il ne copiera à aucune insertion mais en suivant une progression géométrique. – Dario

Questions connexes