Map vs Unordered_map--多线程

时间:2013-08-05 11:06:45

标签: c++ multithreading c++11 map unordered-map

我有以下要求:

我需要一个带键,值对的数据结构(如果有帮助,则键是整数)。

我需要以下操作: -

  1. 迭代(最常用)
  2. 插入(第二次使用)
  3. 按键搜索和删除(最少)
  4. 我打算在结构上使用多个锁来进行并发访问。 什么是理想的数据结构?

    地图或无序地图?

    我认为无序地图是有道理的,因为我可以在O(1)中插入,在O(1)中删除。但我不确定迭代。与地图相比,性能有多糟糕?

    另外,我打算在块上使用多个锁而不是整个结构。这有什么好的实现例子吗?

    谢谢

5 个答案:

答案 0 :(得分:3)

对于两个容器,迭代器递增的速度为O(1),尽管从std::unordered_map可能会获得更好的缓存局部性。

O(log N)的{​​{1}}查找/插入/删除功能较慢外,另一个区别是std::map提供双向迭代器,而速度更快(已摊销的std::map元素访问权限)O(1)仅提供转发迭代器。

Anthony Williams的优秀书籍C++ Concurrency in Action: Practical Multithreading提供了一个多线程std::unordered_map的代码示例,每个条目都有一个锁。如果您正在进行严肃的多线程编码,强烈建议使用本书。

答案 1 :(得分:1)

为什么不简单地使用TBBConcrt中可以找到的现有concurrent_unordered_map

答案 2 :(得分:0)

unordered_map中的迭代不是问题。它比矢量效率稍差,但并不是很大。

与往常一样,您需要针对您的用例进行基准测试,并与其他容器类型进行比较,如果它是您的代码的关键部分。

不确定“块上的多个锁而不是整个结构”是什么意思 - 任何容器更新都需要为整个容器锁定...

答案 3 :(得分:0)

您是否考虑过尝试std::deque推理如下:

  1. 迭代很快 - 数据应该或多或少地打包(与列表不同)
  2. 插入(两端)应该很快 - 双端队列中的数据永远不会调整大小
  3. 迭代和删除缓慢(但不常见的用例)。
  4. 如果最后两种情况很常见,可以使用std::list。还要考虑测试std :: vector`,因为它的缓存效率更高。

    由于迭代哈希表中的大量未使用元素,unordered_map中的迭代可能会很慢。插入将是准确的,直到碰撞级别变得无法容忍,此时整个数据结构将需要重新布局。

    map具有相对快速的迭代,除了数据元素可能相距很远。由于需要重新平衡红黑树,插入可能会很慢。

    unordered_maps的主要用例是快速查找(O1)。法线贴图具有快速查找(O log n)但迭代性能要好得多。

答案 4 :(得分:0)

如果您有实时性要求,我建议将地图覆盖在unordered_map上。 std :: map在100%的时间内保证了性能,但是std :: unordered_map可能会在某些关键角落的情况下进行重新整理并完全破坏实时性能。一般来说,如果我需要绝对保证最坏情况下的性能,我更喜欢红色黑树(std :: map)而不是哈希表(std :: unordered_map)。