2017-05-17 63 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