std::unordered_map包含另一个std::uncodered_map
std::unordered_map containing another std::unordered_map?
我们正在用c++为学校做一个游戏项目。我负责地图对象,它将包含炸弹、玩家、墙和盒子等实体。我的地图上有3个集装箱:
- 玩家的std::列表(多个玩家可以站在同一个箱子上(
- 墙的
std::unordered_map<int, std::unordered_map<int, AEntity*> >
- 另一个
std::unordered_map<int, std::unordered_map<int, AEntity*> >
用于炸弹+盒子
目的是在地图上非常快速地访问一个实体,实体的数量可能非常多。
这就是为什么我想到了无序地图,我计划以这种方式使用它们:
Unordered_map A contain:
KEY: y coord of the Entity || VALUE: pointer to unordered_map B
Unordered_map B contain:
KEY: x coord of the entity || VALUE: pointer to the AEntity instance
问题1:
首先,对于这种使用来说,无序映射的速度那么快吗?我对无序地图很陌生。
问题2:
其次,这是添加元素的可行方式吗?
int main(int ac, char **av)
{
std::unordered_map <int, unordered_map <int, char*>> umap;
(umap[4])[2] = "salut";
std::cout << (umap[4])[2] << std::endl;
}
std::unordered_map
是根据哈希表实现的,而std::map
是根据树实现的。这意味着对于unordered_map
,访问通常是O(1(,其中对于std::map
,访问是O(logn(。这些之间有很多差异,如果你不知道这些差异,我建议你看一本数据结构书,但这里有一些:
对于std::unordered_map
- 分配一个连续的内存数组,您可以使用
reserve()
来防止在不合适的时候调整大小,但是由于哈希表的性质,这总是会分配比您实际使用的更多的空间 - 计算散列很快,但在
std::map
中查找几个指针可能会更快
对于std::map
- 为映射中的每个元素动态分配新内存,如果要向映射中添加数百万个元素,这可能会很慢
- 删除元素也是一项logn操作,如果您经常这样做,操作可能会很慢
- 因为它是一棵树,所以它是排序的,所以可以按顺序遍历元素,这在无序映射中是不可能的
还有很多其他的问题,我建议查一下,在stackoverflow上已经有很多这种类型的问题重复了。
至于第二个问题,这是添加和访问无序映射中元素的有效方法。但是,如果您知道要在地图中放置的项目数量,我强烈建议您使用reserve()
。
其他人已经解释了unordered_map
与map
的区别,但如果你真正追求的是速度,那么我建议使用普通数组(或向量(。你说实体的数量可能"非常大",通过这一点,我理解你正在处理密集的数据(即大多数坐标都包含一个实体(。unordered_map
是一种散列映射,意味着密集的数据将迅速填满存储桶。大存储桶会降低速度并增加内存使用量,从而降低使用unordered_map
的优势。
恢复到阵列将始终以一些额外RAM为代价,提供更快的实体访问和插入。我不知道可能的坐标范围,但假设你的地图范围是(0,0(-(10241024(。为此使用指针数组将只使用1024 x 1024 x 8字节=8MBytes的RAM,无论您在其中存储多少实体。我必须运行一些测试来确保这一点,但我认为,如果映射中80%以上都是实体,那么数组方法实际上会比unordered_map
方法使用更少的RAM。
最后,我还想提一下,你不应该总是关注速度。优化的C++代码通常已经非常快了,除非你真的、真的、真正需要速度,否则我建议你使用最简单的解决方案,而不是最快的解决方案。
unordered_map
容器在需要访问其密钥时比map
容器更快,但在尝试访问其元素的子集时被认为效率较低。我认为,如果直接访问unordered_map
容器中包含的指针,效率会降低。http://www.cplusplus.com/reference/unordered_map/unordered_map/
- 存储在 std::map/std::set 中,与在存储所有数据后对向量进行排序
- 如何在<N>不发生内存泄漏的情况下同时(线程安全)填充 c++11 std::map<std::string,std::bitset*>?
- 无法在 std::map<std::string,std::shared_ptr 中设置值<class>>
- 如何在C++中迭代集合映射(std::map<std::set< char>, int >)?
- 如何初始化结构字段 std::map<std::string, std::string>称为参数
- issue with std::map std::find
- 为什么 std::map< std::map >不释放内存?
- C++ map<std::string> vs map<char *> 性能(我知道,"again?" )
- 确定运行时std::map/std::set的内存使用情况
- 映射上的模板参数无效 std::map< std::string, Stock*> &Stock
- 我的SFINAE检查std::map/std::vector有什么问题
- 使用 std::map<std::string, int> 计算表达式树
- 将数据从两种不同的数据结构插入 std::map <std::string, int> mymap 并通过套接字发送
- 类中的编译器错误,数据类型为 typedef map<std::string,std::p air<std::string,vector<int>>> MapPai
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- 如何填写和访问 std::map<std::p air<enum1, enum2>, funcPtr>?
- 二进制'<':找不到 map<std::string shared_ptr 的运算符<Foo>>
- 如何将 2 个字符* 数组直接映射到 std::map<std::string,std::string>
- C++ std::map<std::string, int> 获取键以特定字符串开头的值
- 从取消引用的迭代器返回 std::map<std::string, int> 时出现巨大的内存泄漏