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_mapboost::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 的更快替代方案的主要内容,如果未能解决你的问题,请参考以下文章

push_back 的更快替代方案(已知大小)

DecimalFormat.format() 的更快替代方案?

iterrows 的更快替代方案

GDI GetPixel() 有更快的替代方案吗?

执行 pandas groupby 操作的更快替代方案

使 mysql 查询更快,或提出替代方案