STL std::map 的更快替代方案
Posted
技术标签:
【中文标题】STL std::map 的更快替代方案【英文标题】:Faster alternative to STL std::map 【发布时间】:2016-07-07 16:11:56 【问题描述】:我确实有一个数据结构:
typedef std::pair<boost::shared_ptr<X>, boost::shared_ptr<X> > pair_ptr;
std::map< pair_ptr, int >
我在迭代过程中使用。在每次迭代中,我 需要 复制 std::map 并可能销毁一个副本。但是,std::map 可以变得很大,超过 100k 个元素。这会显着减慢程序的速度。我已将 operator
inline bool operator<(const pair_ptr& a, const pair_ptr& b)
return (a.first < b.first) or
(a.first == b.first and a.second < b.second);
我使用 std::map 复制构造函数和析构函数。有更快的替代方案吗?
【问题讨论】:
重新设计你的程序,这样你就不需要在每个迭代周围复制巨大的地图。 你考虑过unordered_map
吗?
你看过std::unordered_map
或boost::flat_map
吗?
如果问题确实是由于复制造成的,我怀疑复制一个巨大的unordered_map
会比复制一个巨大的map
快得多。访问其中的元素可能会更快,但不能复制它。复制它仍然需要分配 100k 节点并将它们链接在一起。
我支持 Ocelot。即使flat_map
也无济于事,因为尽管要复制的分配要少得多,但您仍在进行数十万次原子增量/减量。这是一个算法问题,最好有算法解决方案。
【参考方案1】:
您有很多选择 - 我们可以建议设计替代方案,但没有足够的信息来为您制作。
你可以做以下三件事:
您能否将键设置为指向对的指针(并调整 适当地比较),以便对本身(包含 两个 refcnt'd ptrs) 不必复制?
在每次迭代中 - 您是否需要预期的 O(log n)
插入/删除时间?如果你能和O(n)
住在一起
插入/删除然后你可以使用排序的向量作为容器吗
而不是地图? (这样您就可以在一个容器中分配/释放容器
拍摄而不是分配/释放大量的小树节点。)(记住:std::map
不是您可以搜索的唯一数据结构,甚至不是唯一的std::
数据结构。所有可搜索的数据结构都可以使用,只需选择
具有适当复杂性保证的那个,以您的为模
“常量”的知识(例如,堆分配很昂贵),为您
用例。)
你能(你)管理两件事情的生命周期吗?关键是 指点独立的图,还有这个迭代过程?如果 所以你可以拥有一对裸指针的键,这将比 ref cnt'd 在每个迭代器处创建新映射的指针。你 可以有一组单独的 ref cnt'd 指针指向你所有的东西, 并在那里管理这些对象的生命周期。
这些也可以组合。只是一些帮助您入门的想法。
【讨论】:
这些是一些很好的建议。 1) 绝对有可能; 2)最接近我想知道的; 3) 我不太热衷于使用裸指针,但这也是一种选择。 从上面的讨论看来,这似乎是完全避免复制的最佳方法,即使这需要进行一些实质性的重构。这就是我要做的。以上是关于STL std::map 的更快替代方案的主要内容,如果未能解决你的问题,请参考以下文章