在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
并且使用CCD_ 1从盘中读取。之后,条目保持不变。
许多元组的差异仅在于1个值,即有许多值出现在相当多的条目中。我想利用这个事实,不要经常存储不必要的值。
我试过一系列像这样的地图
std::map<u32, std::map<u32, std::map<u32, std::map<u32, std::map<u8,f32>>>>> costsMap_;
但这太慢了,因为在短短几分钟内就有数百万次查找,因此查找也必须相当快(它还没有完全优化到运行时)。
有没有一种方法可以将表加载到内存中,从而使内存消耗显著下降(至少下降2倍),同时在运行时不会损失太多速度?
您可以通过按最常见前缀的长度拆分元组来减少重叠,而不是在每个级别进行拆分。
例如,假设您的数据在元组的前三个成员上有大量重叠,即,如果您只考虑映射中每个元组的前3个成员,则不同条目的数量会下降几个数量级。在这种情况下,您可以将地图拆分为多个地图。我还建议使用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_;
除了最后一个查找键之外的所有查找键都"融合"到一个元组中。
相关文章:
- C++:TypeDef使用元组
- Pybind11:将元组列表从Python传递到C++
- 重载元组索引运算符-C++
- 在C++中,如何通过几种类型从元组中选择多个元素
- 将fold表达式与std::一起用于两个元组
- std::ranges::elements_view,用于自定义类似元组的数据
- 在boost::hana中给定一个键元组,如何从映射中获取值元组
- 编译按映射类型获取元素的映射错误元组
- std::元组到元组的映射和使用 emplace
- 带有映射的 Lambda 函数,其中键是元组,值是双精度
- 整数和元组的静态 STL 映射返回 0
- C++映射中搜索元组错误:无法将"int"左值绑定到"int&&"
- c++存储映射元组的引用,以便在另一个函数中使用
- 复制地图<双精度,元组<双精度,双精度>>映射<双精度,双精度>没有循环?
- 如何实现可变元组映射操作
- 使用C++元组类型作为映射中的键
- 如何在Boost中使用元组映射
- 为不使用元组的自定义映射模拟std::map迭代器
- 将C++重载函数映射到异构元组上
- 在C++中,在不损失速度的情况下提高元组映射的内存消耗