我想定义一个类似的地图
std::unordered_map<int, std::unordered_set<int>>
要么
std::unordered_map<int, std::unique_ptr<std::unordered_set<int>>>
我不确定哪一个更好。
我看不出第一个是否有任何问题。就Does std::map::iterator return a copy of value or a value itself?而言 第一个是安全的,因为每组地图的访问权也应该是参考类型。
如果是这样,哪一个更好?
答案 0 :(得分:1)
我更喜欢std::unordered_map<int, std::unordered_set<int>>
。大多数C ++容器由一种“头”数据结构组成,包含指向实际数据的指针(例如,std :: vector只是一个包含指向实际底层'数组'数据的指针的类)。这个'header'数据结构通常相对较小,所以如果你要存储std::unique_ptr
,内存分配的实际开销(CPU时间开销和内存开销)都会相对较大。
另一方面,如果您的问题需要您有效地看到std::unordered_map
中的条目为“空”,并且/或者您将在地图中包含大量这些空条目,请使用{{ 1}}可能更有效率。
另请注意,std::unique_ptr
和std::set
等容器的内存开销相对较大。如果该集合仅包含少量元素,请考虑使用std::map
而不是std:vector
。循环使用小向量来检查重复项可能比使用std::set
的散列逻辑更有效(因为std::set
的内存局部性将更有效地使用处理器内存缓存,请参阅演示文稿Chandler Carruth对CPPCON2014的评论,https://www.youtube.com/watch?v=fHNmRkzxHWs)。
答案 1 :(得分:0)
如果你想知道什么是最好的,你需要定义你的效用函数。
你在优化什么?问题就在于,我个人可以说,我更喜欢打字,所以std::unordered_map<int, std::unordered_set<int>>
最好。但是,这可能不是你的效用函数。
如果您关注性能,那么如果使用std::unique_ptr
,额外的间接级别将花费您,分配,跳和缓存加载。如果您在集合之间共享集合,那么std::shared_ptr
将花费一跳但保持一致性并降低总体内存。
如果您的设置很小,经常是空的或经常更新,那么使用std::unordered_map<int,std::set<int>>
在某些用例中,您还可以组合地图和设置键,然后使用std::unordered_set<std::pair<int, int> >
如果支持,则std::tuple<int, int>
。
答案 2 :(得分:0)
std::unordered_map<int, std::unique_ptr<std::unordered_set<int>>>
这看起来很多余。 unique_ptr
的全部意义在于,当它超出范围时 - 它会删除并破坏它指向的内容。
如果你的地图的值是一些需要删除的指针 - 继续。但你的价值是std::unordered_set
即使没有指针也会被销毁和删除
因此,您基本上可以在智能指针上添加额外的创建和删除,而无需添加任何额外的功能。