Datenstruktur entspricht Map (in Java) für große Datenmengen

7

Gibt es eine bereits implementierte Datenstruktur, die ich verwenden kann, um einem Objekt zuzuordnen? (in meinem Fall eine Kante), eine ganze Zahl? Ich lese ein Diagramm aus einer Datei, 10 Mil Scheitelpunkte, 60 Mil Kanten und ich zuweisen zu jeder Kante, eine Kosten, mit einer Karte (costs.put (e, Kosten)).

Ich erstelle die Kosten-Map auf diese Weise:

%Vor%

Die Ausnahme, die es gibt, ist:

%Vor%     
Radu Stejerean 31.10.2012, 09:12
quelle

8 Antworten

6

HashMap ist die korrekte Datenstruktur für eine Basis Map . Das Problem, das Sie haben, ist, dass die JVM nicht angewiesen wird, genügend Speicherplatz zu reservieren, um den Dateiinhalt im Speicher zu behalten. Starten Sie die JVM mit einem -Xmx -Flag. Zum Beispiel erlaubt es -Xmx1G -Parameter, 1 Gigabyte Speicher zu verwenden.

    
Tim Bender 31.10.2012, 09:17
quelle
6

Sie haben 6e7 Kanten. Ein einfaches Objekt benötigt 24 Bytes (64-Bit-HotSpot), also genau dort sind 1.449 Bytes (1.5 GB). Jetzt stellen Sie die effizienteste Karte vor, die Sie sich vorstellen können, indem Sie nur 6e7-Referenzen plus 6e7 Integer -Objekte hinzufügen. Das sind weitere 2.4e8 Bytes für die refs und 1.44e9 Bytes für die Integer s: weitere 1.5 GB, die Summe beträgt jetzt 3 GB - und das ist die theoretische Untergrenze für Ihr Problem (Modulo-Caching) , siehe unten).

Gestützt darauf schlage ich vor, dass Sie Ihre Edge -Klasse um ein weiteres int -Feld erweitern. Dies wird Ihren Speicherbedarf drastisch reduzieren.

Wenn dies jedoch keine Option ist und:

  • all Ihre Ganzzahlen überschreiten selten zwei Ziffern,
  • Achten Sie darauf, niemals new Integer , sondern Integer.valueOf , Autoboxing usw.,
  • zu verwenden
  • Sie verwenden Java 7,

Sie profitieren automatisch von dem integrierten kleinen Integer-Cache. Wenn die Ganzzahlen Werte aus einem größeren Bereich annehmen, aber immer noch sehr dupliziert werden, ist ein benutzerdefinierter Cache sehr empfehlenswert.

    
Marko Topolnik 31.10.2012 09:24
quelle
3

Zusätzlich zum Ändern der jvms-Speichereinstellungen können Sie HashMap s Speicherverwaltung mit Anfangskapazität und Lastausgleich optimieren.

Javadoc Auszug:

  

Eine Instanz von HashMap hat zwei Parameter, die ihre Leistung beeinflussen:   Anfangskapazität und Lastfaktor. Die Kapazität ist die Anzahl von   Buckets in der Hash-Tabelle, und die anfängliche Kapazität ist einfach die   Kapazität zum Zeitpunkt der Erstellung der Hash-Tabelle. Der Ladefaktor ist a   Maß dafür, wie voll die Hash-Tabelle vor ihrer ist   Die Kapazität wird automatisch erhöht. Wenn die Anzahl der Einträge in der   Hash-Tabelle überschreitet das Produkt aus Ladefaktor und Strom   Kapazität wird die Hash-Tabelle aktualisiert (dh interne Daten)   Strukturen werden neu aufgebaut), so dass die Hash-Tabelle ungefähr zweimal vorhanden ist   die Anzahl der Buckets.

    
atamanroman 31.10.2012 09:20
quelle
3

Anstatt ein HashMap

zu erstellen %Vor%

Sie können Kosten innerhalb von Edge Objekt speichern.

%Vor%

Auf diese Weise können Sie etwas Speicher im System speichern.

    
Azodious 31.10.2012 09:21
quelle
2

Zurück zum ursprünglichen Problem: Sie haben Kanten, die Kosten haben. Da Ihr Diagramm spärlich ist, warum nicht eine dünn besetzte Matrix verwenden? Vielleicht ist ein Objekt-zu-Integer-Mapping nicht das, was Sie wirklich brauchen und wollen. Sie können apache.commons.math betrachten, ich denke, sie haben dünn besetzte Matrizen. Außerdem müssen Sie darüber nachdenken, wie Sie auf die Kosten in Ihren Algorithmen zugreifen, um das richtige Sparse-Format zu wählen (spaltenbasiertes Lauflängencodieren / zeilenbasiertes rle oder etwas anderes). Oder es ist dir egal, und verwenden Sie alle, aber dann sollten Sie das Ding am Anfang Ihrer Algorithmen konvertieren.

    
kutschkem 31.10.2012 09:22
quelle
1

Sie erkennen, dass dies eine ganze Menge RAM erfordert, oder? Probieren Sie die Größe des Heapspeichers zu erhöhen , und alles wird gut ...

>

Und um Ihre ursprüngliche Frage zu beantworten: Ja, das ist es, was Karte s sind für ...

    
ppeterka 31.10.2012 09:17
quelle
1

Sie müssen pro Projekt angeben, wie viel Heap-Speicherplatz Ihr Projekt benötigt

Ich denke, Sie könnten diesem Schritt folgen:

%Vor%     
Ami 31.10.2012 09:18
quelle
1

Vielleicht suchen Sie nach TObjectIntHashMap Dies ist ähnlich wie in HashMap<Edge, Integer> , außer dass es int als primitives Element speichert, wodurch möglicherweise etwas Speicher gespart wird. Diese Sammlung kann auch geringfügig schneller sein, wenn die Sammlung größer ist (weil sie besser in den Cache passt)

%Vor%     
Peter Lawrey 31.10.2012 09:46
quelle

Tags und Links