2017-05-17 8 views
2

Ich habe 10.000.000 Einträge vom Typ struct {int, int, int, int}. wenn ich speichern sie QHash oder QMap verwendet wird, nimmt es große Menge an Speicher, in der Tat muss es überQHash Speicherung großer Datenmengen

10,000,000 * 4 * 4 (sizeof integer) <= 153 MB 

nehmen, aber wenn ich meine Daten laden dauert es etwa 1,2 GB für beide QHash und QMap, warum dies geschieht und wie kann ich es für Geschwindigkeit und Speicher optimieren? (durch irgendeine andere Datenstruktur oder einige Tricks zu qmap und qhash)

+2

'QHash' und' QMap' sind assoziative Container: Raten Ihrer 4-int-Struktur ist der gespeicherte Wert, was ist der Typ der Schlüssel? – wasthishelpful

+0

@washishelpful Schlüssel sind vier andere Ganzzahlen, die ich sie mit QtPrivate :: QHashCombine für qhash() speichern – abdolahS

+1

Es wäre wahrscheinlich in der Nähe von 153 MB, wenn es ein sequenzielles Array ist, aber Karten haben zusätzliche Datenstruktur Overhead und Heap-Allokation Overhead. Es sollte trotzdem nicht so viel sein. – dtech

Antwort

2

Sie haben im Kommentar gesagt, dass Sie andere vier Eingänge als Schlüssel verwenden - diese Werte müssen auch gespeichert werden, so speichern Sie tatsächlich 8 Ints, nicht 4. Darüber hinaus muss QHash den Wert des Hash speichern, um die Werte basierend auf dem Schlüssel effizient zu suchen. Der Hash ist eine vorzeichenlose Ganzzahl. Sie haben also 9 Werte, die jeweils 4 Byte lang sind. Es beläuft sich auf ~ 350 MB.

Auch intern QHash oder QMap kann eine gewisse Polsterung zwischen seinen Elementen, beispielsweise data structure alignment requirements zu befriedigen. Padding ist ein Multiplikator von 1 Byte, was bedeutet, dass wir im Fall von 10 Millionen Elementen mindestens einige Dutzend zusätzliche Megabyte erhalten können.

Außerdem QHash und QMap sind nicht nur Rohdaten - sie beide verwenden, um zusätzliche Hinweise auf ihre internen Datenstrukturen usw., die noch ein weiterer Grund, warum ein einzelner Eintrag mehr Platz in Anspruch nehmen würde, als Sie erwartet haben.

Eine weitere Quelle der Datenmenge könnte die Tatsache sein, dass diese Klassen aus Effizienzgründen einige zusätzliche Werte speichern können, sodass sie vorberechnet werden, wenn Sie einige ihrer Methoden aufrufen.

Last but not least, QHash reserviert aus Effizienzgründen mehr Speicher als seine aktuellen Elemente in einem bestimmten Moment benötigen (unnötiges Kopieren zu vermeiden). Ich würde erwarten, dass je größer die Größe, desto mehr Speicher würde es nur für den Fall reservieren, weil das Kopieren teurer wird. Sie können den im Voraus reservierten Speicher überprüfen, indem Sie die Kapazität() Methode aufrufen. Wenn Sie die reservierte Speicherkapazität begrenzen möchten, rufen Sie die Methode squeeze() auf, um den Speicher so anzupassen, dass er gerade ausreicht, um die aktuell gespeicherten Elemente zu enthalten.

+0

Anstatt _squeeze_ zu verwenden, ist es besser _reserve_ zu verwenden, da er die Anzahl der Elemente kennt. – Zlatomir

+0

Wenn Sie reserve() aufrufen und dann Elemente einfügen, ist die Implementierung frei, während des Einfügevorgangs mehr Speicherplatz zu reservieren, so dass Sie am Ende trotzdem squeeze() aufrufen können, nur um sicher zu gehen. – KjMag

Verwandte Themen