2016-06-20 39 views
0

Derzeit habe ich eine Lösung, wo ich Objekte, die mich interessieren, verfolgen, indem ich ihren Hashcode über Object.GetHashCode erhalte und sie dann in einem HashSet<int> speichern.Ist es möglich, Hashcodes als Bitmaske zu verwenden, um Sammlungsmitgliedschaft effizient zu speichern/zu verfolgen?

Allerdings habe ich auch über Bitmasken und bitweise Operationen gelernt, und ich bin ziemlich fasziniert von ihnen. Here is a great question, die ich in der Nähe zu dem, was ich suche, gefunden habe. Ich kann jedoch nicht scheinen, dass dies effizient für Hash-Codes funktioniert.

There is also this question, aber es scheint sich mit 5-Bit-Nummern zu beschäftigen, wenn Hash-Codes int 's (32-Bit) sind.

Ich bekomme die Lösung (von der ersten referenzierten Frage) funktioniert, aber es ist nicht so schnell wie meine aktuelle HashSet-Ansatz ist. Dies ist auf die schiere Anzahl der Elemente in zurückzuführen, die erstellt werden müssen, um alle bekannten Hash-Codes zu berücksichtigen (int.MaxValue).

Gibt es eine bitmask/bitweise Operation, die ich bei der Arbeit mit einem BitArray berücksichtigen sollte? Oder bin ich hier völlig ausgetreten und sollte einfach bei meiner HashSet<int> Lösung bleiben?

+0

fyi verwenden Sie gethashcode nicht, Kollision kann leicht passieren! http: // Stapelüberlauf.com/questions/7968753/Wahrscheinlichkeit-erhalten-ein-Duplikat-Wert-wenn-Aufruf-gethashcode-on-Strings – Fredou

+0

Sie sollten speichern * die Objekte selbst * in der 'HashSet', nicht speichern ihre' GetHashCode' Werte . Indem Sie nur die Hashes speichern, entfernen Sie die Fähigkeit des 'HashSet', Kollisionen zu verwalten. Was den Rest der Frage betrifft, so basiert dies auf der Prämisse, dass der Hash für jedes Objekt einzigartig ist, aber das ist eine falsche Annahme, so dass Sie das nicht tun können. Legen Sie die Gegenstände einfach in ein 'HashSet'. – Servy

+0

@Servy, das ist ein guter Punkt, und Sie haben mich mein Design hier überdenken lassen. Ich hatte gehofft, Informationen zu speichern, ohne eine starke Referenz in Erinnerung an das Objekt zu erstellen und es so schnell wie möglich zu machen. Klingt so, als ob ich schon die Lösung gefunden hätte (nur dafür, dass ich das gemacht habe!). –

Antwort

0

Dies war in der Tat ein Beispiel für einen ausgetretenen Pfad, gepaart mit einem Missverständnis der Referenzen/Speicherverwaltung. In meinem Fall habe ich ein Objekt Dictionary<TKey, TValue> verwendet, um zwischengespeicherte Ergebnisse aus Methodenaufrufen für eine Instanz zu speichern. Ich konnte keine ConditionalWeakTable weil es mindestens drei Teile zu einem Schlüssel verwenden:

  1. Die Instanz, die die Methode enthält, wo die Ergebnisse im Cache gespeichert werden.
  2. Diese Methode.
  3. Argumente, die an die Methode übergeben werden.

Wenn ich früher ein ConditionalWeakTable ich hätte „noch eine weitere Aufgabe“ erstellen (Klasse), die noch eine andere Zuordnung erfordern würde, aber schlimmer wäre noch nicht alles verwiesen werden (neben dem ConditionalWeakTable) und würde sich Müll gesammelt auf den ersten Durchgang (das ist in der Tat related to another open -- but now also solved -- question of mine).

Nach vielen Überlegungen habe ich festgestellt, dass die Antwort tatsächlich in ConditionalWeakTable liegt. Anstatt die drei oben genannten Elemente als Schlüssel zu verwenden, verwenden Sie eine Delegate, die aus den Teilen 1 und 2 besteht, und verbinden Sie dann eine Dictionary mit dieser.

Oder als Feldinitialisierung zu setzen:

readonly ConditionalWeakTable<Delegate, Dictionary<object[], object>> cache = new ConditionalWeakTable<Delegate, Dictionary<object[], object>>(); 

(Bemerkenswert ist auch die Verwendung eines StructuralEqualityComparer mit dem obigen Wörterbuch diese Arbeit zu machen).

Dies tut natürlich alles, was ich will. Es wird Objekte verfolgen, bis das referenzierte Objekt, das die Methode enthält (und aus der Delegate besteht), aus dem Speicher gelöscht wird. An diesem Punkt wird auch das zwischengespeicherte Wörterbuch freigegeben, wobei alle Inhalte gelöscht werden.