繁体   English   中英

在不损失C ++速度的情况下,提高元组映射的内存消耗

[英]Improve memory consumption of a map of tuples without losing speed in C++

为了存储5元组的成本,我有一张如下地图:

std::map<std::tr1::tuple<u32, u32, u32, u32, u8>, f32> costsMap_;

在运行时期间有几个这样的表要加载到内存中,每个表都有大约。 2.5 *10⁷条目。 每个条目都有表格

2.16345 # 5875 396 # 47512 26445 # 2

并使用std::inputstream从磁盘读取。 之后,参赛作品保持不变。

许多元组仅在1个值上有所不同,即有许多值出现在相当多的条目中。 我想过要利用这个事实,而不是经常不必要地存储价值。

我尝试了一系列地图的地图

std::map<u32, std::map<u32, std::map<u32, std::map<u32, std::map<u8,f32>>>>> costsMap_;

但这太慢了,因为只需几分钟即可查找数百万次,因此查找速度必须相当快(它还没有完全针对运行时进行优化)。

有没有办法将表加载到内存中,以便内存消耗显着下降(至少2倍)而不会在运行时同时损失太多速度?

您可以通过将元组拆分为最常见前缀的长度来减少重叠,而不是在每个级别拆分它。

例如,假设您的数据在元组的前三个成员上有大量重叠,即如果您只考虑映射中每个元组的前三个成员,则不同条目的数量会下降几个大小。 在这种情况下,您可以将地图拆分为地图地图。 我还建议使用unordered_map ,因为它渐近更快。

std::unordered_map<std::tr1::tuple<u32,u32,u32>,std::unordered_map<std::tr1::tuple<u32,u8>,f32> > costsMap_;

这种方法以额外查找为代价减少了密钥存储的重复。 只有当您存储的元组前缀之间的重复数量足以证明额外查找的合理性时,才能节省成本。

请注意,这种方法是您在帖子中建议的地图扩展方法的概括,前三个和后两个位置“融合”到元组中。 您可以为拆分选择其他点 - 例如,如果前四个键经常重复,则可以使用

std::unordered_map<std::tr1::tuple<u32,u32,u32,u32>,std::unordered_map<u8,f32> > costsMap_;

除了最后一个查找键之外的所有键都“融合”成一个元组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM