2017-05-17 43 views
2

我有10,000,000條類型的結構{int,int,int,int}。當我保存他們使用QHashQMap,其佔用大量的內存,實際上它必須採取有關QHash存儲大量的數據

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

,但是當我打開我的數據,大約需要1.2 GB兩種QHash和QMAP,​​會出現這種情況,以及如何我可以優化它的速度和內存嗎?(通過任何其他數據結構或一些技巧qmap和qhash)

+2

'QHash'和'QMap'是關聯容器:猜測你的4-int結構是存儲的值,鍵的類型是什麼? – wasthishelpful

+0

@wasthishelpful鍵是我使用QtPrivate :: QHashCombine存儲它們的另外四個整數qhash() – abdolahS

+1

如果它是一個連續數組,它可能接近153 MB,但映射有額外的數據結構開銷和堆分配開銷。儘管如此,它仍然不應該如此。 – dtech

回答

2

你已經在評論中說,你使用另外四個int作爲鍵 - 這些值也必須被保存,所以你實際上存儲了8個整數,而不是4個。除此之外,QHash必須存儲散列的值以有效地查找基於密鑰的值。散列是一個無符號整數,所以你有9個值,每個4個字節長。它總計高達350 MB。

此外,內部QHashQMAP可以使用其的元件之間一些填充,例如,以滿足data structure alignment requirements。填充是1個字節的乘數,這意味着如果有10萬個元素,我們可能會得到至少幾十個額外的兆字節。

此外,QHashQMAP不只是原始數據 - 它們都使用額外的指針,其內部數據結構等,這是另一個原因,一個單一的入口將採取比你預期的更多的空間。

數據大小膨脹的另一個原因可能是出於效率的原因,這些類可能會存儲一些附加值,以便在您調用某些方法時進行預計算。

最後但並非最不重要的一點,QHash由於效率原因(避免不必要的複製),在任何特定時刻都會保留比當前元素更多的內存。我認爲,尺寸越大,爲防萬一,它將保留越多的內存,因爲複製變得更加昂貴。 您可以通過調用容量()方法來檢查預先保留的內存。如果要限制保留的內存量,請調用squeeze()方法來定製內存,以便它足以包含當前存儲的元素。

+0

而不是使用_squeeze_,最好使用_reserve_,因爲他知道元素的數量。 – Zlatomir

+0

如果您調用reserve()並插入元素,則在插入過程中實現可以自由保留更多空間,因此無論如何您最終都可以調用squeeze()來確保。 – KjMag