Ich habe ein Projekt, das eine große Datenmenge verarbeitet, die in eine Excel-Datei geschrieben wird. Ich speichere diese Daten in einer statischen HashMap in der Form Map<List<String>, Integer>
, wobei die Größe der Liste nur 3 ist. Die Anzahl der Einträge in der Map kann jedoch irgendwo zwischen 0 und 11.300 liegen.Speicher Effiziente Methode zum Behandeln einer großen HashMap
Der Fluss dieses Projekts ist:
laden Karte oben mit Einträgen
Iterate Karte und tun Sachen
- löschen Karte für den nächsten Satz von Einträgen
Was ich kürzlich über HashMap herausgefunden habe, ist, wie es die Größe ändert, wenn die eingestellte Größe verletzt wird. Meine Map wird also nicht nur ständig auf dramatische Längen angepasst, sondern es könnte auch sehr gut 20.000 leere Einträge enthalten, wenn ich den größten Satz von Einträgen lösche.
Also ich versuche, dieses Ding Mikro-optimieren, und ich bin mit einem Dilemma fest, wie dies zu tun ist. Meine beiden Gedanken sind:
Stellen Sie den Standardwert des anfänglichen HashMap auf einen Wert, der es erlauben würde, die meisten immer nur einmal die Größe neu
Reinitialize die HashMap mit der durchschnittlichen Größe, die Neudimensionierung und erlauben den Garbage Collector wird für jeden neuen Eintrag Set erwartet zu begrenzen einige bis reinige
Meine Intuition sagt mir, Option zwei könnte die vernünftigste sein, aber das könnte noch unter Beweis stellen für viele Größenänderung abhängig vom nächsten Eintragssatz. Aber dann beschränkt die erste Option die Größenanpassung auf eine einmalige Operation, lässt dann aber buchstäblich Tausende von Null-Einträgen übrig.
Sind eine meiner zwei vorgeschlagenen Lösungen besser als die andere, gibt es nicht viel Unterschied in der Speicherverbesserung zwischen den beiden, oder könnte es eine andere Lösung geben, die ich übersehen habe (was die Datenstruktur nicht verändert)?
EDIT: Nur für einen Kontext, ich möchte dies tun, weil gelegentlich das Projekt aus Heap-Speicher läuft und ich versuche zu bestimmen, wie viel von Auswirkungen dieser gigantischen Karte ist oder sein könnte.
EDIT2: Nur um zu verdeutlichen, ist die Größe der Map selbst der größere Wert. Die Schlüsselgröße (dh der Liste) ist immer nur am 3.
Tun Sie nicht die Option 2. Wenn Sie genug Speicher haben, um den schlimmsten Fall zu bewältigen, d. H. 11300 'List'-Objekte als Schlüssel zum Zuordnen, dann haben Sie genug Speicher für den gesamten Prozess. Es gibt nichts wirklich gewonnenes, wenn man die Karte schrumpft, aber man verliert Leistung durch die erneute Expansion. Die durch die Schrumpfung gespeicherte Speichermenge ist minimal, verglichen mit allem anderen. Dies ist oder vorausgesetzt, es ist ein kontinuierlicher Prozess. Bewahre die große, aber leere Karte nicht für längere Zeit auf, ohne sie zu benutzen. In diesem Fall entfernen Sie die Karte und weisen Sie sie als nächstes neu zu. – Andreas
Gibt es einen Grund, warum Sie TreeMap nicht verwenden können? Ich denke nicht, dass es merklich langsamer wäre (log_2 (11300) ist nur 13) und es wird kein verschwendeter Speicherplatz übrig bleiben. –
@Oliver Der Map-Key ist eine 'List', die nicht 'Comparable' ist und die Verwendung von' TreeMap' verhindert. Könnte einen benutzerdefinierten "Comparator" liefern, aber dann müssten Sie sich noch für eine Reihenfolge der Listen entscheiden, die möglicherweise nicht durchführbar ist. Außerdem verwendet eine 'TreeMap' mehr Speicherplatz als eine' HashMap'. – Andreas