Ich arbeite gerade an einem programmatischen Problem, bei dem ich versucht habe, eine riesige Menge von Daten zu erstellen. Der Schlüssel für die Daten ist eine benutzerdefinierte Low-Memory-Implementierung einer CharSequence, die hashCode () und equals (...) implementiert und der Wert ist ein Integer-Objekt.
Es kann Millionen von Einträgen in dieser Hashtabelle geben, und es ist mir gelungen, die Speicherbelegung für den Wert drastisch zu reduzieren, indem ich Integer als Zeiger in einer Datei auf die Daten habe, die ich hashen möchte von Bytes (durchschnittlich 25 Bytes) und dass die Schlüssel in der Standardimplementierung von HashMap im Speicher gehalten werden müssen.
Ich brauche eine Hashmap, die einen geringen Speicheraufwand hat und möglicherweise die Schlüssel auf die Festplatte puffern oder alternativ eine Hash-Darstellung der Schlüssel speichern kann. Wenn die Schlüssel selbst hashed sind, würde ich über Hash-Kollisionen besorgt sein.
Idealerweise möchte ich in der Lage sein, eine Million Einträge in der Karte pro 50 MB Heap-Speicher zu speichern (ein Byte-Array von 25 Bytes im Schlüssel- und Integer-Objekt im Wertteil).
Hat jemand Erfahrung mit Kartensystemen mit wenig Speicher, die durch das Dateisystem unterstützt werden, die für die Reduzierung des Platzbedarfs der Schlüssel optimiert wurden?
Danke,
Chris
Sie könnten die Java-Hash-Map verwenden und eine FileKey-Klasse schreiben, die eine RandomAccessFile, Offset und Länge verwendet, den Hash bei der Konstruktion vorberechnet und Comparable implementiert, indem sie die Daten aus der Datei nur für den Vergleich liest.
In Verbindung mit einem einfachen MRU-Cache können Sie eine bestimmte Anzahl von Schlüsseln im Speicher behalten, indem Sie eine andere Hashmap verwenden, die auf denselben Schlüsseln kodiert ist, aber einen benutzerdefinierten Vergleicher verwendet, der nur die Offset- und Längenwerte vergleicht ).
Wie wäre es mit Berkeley DB Java Edition ? Seine StoredMap -Klasse sieht aus wie du bist suchen.
Ich denke, dass der Standardwert HashSet
kein schlechter Weg ist - machen Sie das Schlüssel / Wert-Paar selbst (Sie müssen es also nicht in ein zusätzliches Objekt einfügen). Es ist ziemlich speichereffizient auf diese Weise; es erfordert wirklich nur ungefähr (1 / loadFactor) ^ (3/2) * 4 Bytes mehr Speicher oben auf Ihrem Schlüsselobjekt + 4 Bytes für den Wert. In der Praxis sollte dies etwa 8 Byte Overhead pro Eintrag hinzufügen. (Sie können dies weiter reduzieren, wenn Sie im Voraus wissen, wie viele Schlüssel Sie speichern werden.)
Tags und Links java performance collections hashmap hashtable