J'utilise un dictionnaire pour accumuler le nombre d'occurrences de clés et, par conséquent, l'opération principale écrit une paire de valeurs de clé lorsque la valeur est la valeur précédente plus une ou une seule valeur précédente. Cependant, cela nécessite deux opérations de dictionnaire distinctes (lire et écrire) lorsque je pouvais simplement faire un ( Je remarque que le dictionnaire simultané prend en charge Par conséquent, un dictionnaire de références à des INT mutables est plus rapide. Cependant, cela introduit des références inutiles, ce qui signifie des allocations de tas et d'écrire des barrières. Donc, je suppose que cela est possible de faire de manière significative meilleure mais je ne peux pas voir comment sans réécriture addorupdate code>). P>
addorupdate code> mais le dictionnaire
ordinaire générique code> n'apparaît pas. P>
dictionnaire code> à partir de zéro. Ai-je raison? P>
3 Réponses :
Une mise à jour du dictionnaire ne nécessite pas de recherches multiples si vous utilisez des types de référence:
Dites que vous avez un dictionnaire dictionnaire
foo code> est Un type de référence et comprend un
Nombre Code> Propriété: P>
void UpdateCount(string key)
{
Foo f;
if (dict.TryGetValue(key, out f))
{
// do the update
++f.Count;
}
else
{
dict[key] = 1;
}
}
Comme Jim Mischel mentionné - il est impossible de faire une recherche unique pour la modification de la valeur de l'article du dictionnaire.
ConcurrentDrictionary.addorUpdate CODE> Méthode effectuez plusieurs opérations de recherche (sources réfléchies):
ConcurrentDictionary: 2504
Dictionary: 1351
Vous pouvez faire quelque chose comme ceci:
private class Counter { public string Key { get ; set ; } public int Frequency { get ; set ; } } ... Dictionary<string,Counter> frequencyTable = new Dictionary<string,Counter>() ; ... string someKey = GetKeyToLookup() ; Counter item = null ; bool hit = frequencyTable.TryGetValue( someKey,out item ) ; if ( !hit ) { item = new Counter{ Key=someKey,Frequency=0 } ; } ++ item.Frequency ;
Oui, c'est exactement ce que je voulais dire par "un dictionnaire de références à des INT mutables est plus rapide" mais qui introduit des références inutiles, ce qui signifie des allocations de tas et d'écrire des barrières.
@Jonharrop l'avez-vous essayé? C5 est-il effectivement plus efficace pour cette tâche? Est la deuxième recherche ou le type de référence plus coûteux?
Je l'ai essayé avec mon propre code (pas C5) et le dictionnaire des références mutables était plus rapide que double recherche sur un dictionnaire de valeurs. La seconde recherche est plus chère. Cependant, un dictionnaire qui permet une complément serait la solution la plus rapide, bien sûr.
Vous essayez donc d'éliminer l'une des recherches dans un scénario d'ajout ou de mise à jour?
Un dictionnaire simultané semble assez performant dans de nombreux cas, avez-vous vérifié s'il fournit des performances suffisantes pour votre scénario?
Pouvez-vous trier les valeurs de clé? Je suppose que la plupart seront O (n log n) afin que vous puissiez avoir à tester la meilleure performance
Peut-être que vous pourriez essayer d'utiliser un tableau avec des numérations d'éléments et du dictionnaire de clé / Index-in-TRay - cela nécessitera une recherche dictionnaire et une indexation de tableau - peut être un peu plus rapide dans les cas extrêmes
On dirait que vous avez raison, vous pouvez faire un peu mieux. Une alternative pratique à écrire à partir de zéro commence à partir de la mise en œuvre de la mono: github.com/mono/mono/blob/master/mcs/class/corlib/...