简体   繁体   中英

Map vs Unordered_map— Multithreading

I have the following requirements:

I need a datastructure with key,value pairs(keys are integers if that helps).

I need the below operations:-

  1. Iteration(most used)
  2. Insertion (2nd most used)
  3. Searching by key and deletion(least)

I plan to use multiple locks over the structure for concurrent access. What is the ideal data structure to use?

Map or an unordered map?

I think unordered map makes sense, because i can insert in O(1), delete in O(1). But i am not sure of the iteration. How bad is the performance when compared to map?

Also, i plan to use multiple locks on blocks instead of the whole structure. Any good implementation example of this?

Thanks

The speed of iterator incrementing is O(1) for both containers, although you might get somewhat better cache locality from std::unordered_map .

Apart from the slower O(log N) find/insert/erase functionality of std::map , one other difference is that std::map provides bidirectional iterators, whereas the faster (amortized O(1) element access) std::unordered_map only provides forward iterators.

The excellent book C++ Concurrency in Action: Practical Multithreading by Anthony Williams provides a code example of a multithreaded unordered_map with a lock per entry. This book is highly recommended if you are doing serious multithreaded coding.

为什么不直接使用现有的concurrent_unordered_map ,你可以在这两个发现TBBConcrt

Iteration is not a problem in an unordered_map . It is a little less efficient than a vector, but not largely so.

As always, you will need to benchmark for YOUR use-cases, and compare with other container types if it's a critical part of your code.

Not sure what you mean by "multiple locks on blocks instead of the whole structure" - any container updates will need to be locked for the whole container...

Have you thought about trying a std::deque The reasoning being as follows:

  1. Iteration is fast - data should be more or less packed close (unlike lists)
  2. Insertion (at either end) should be quick - data in a deque is never resized
  3. Iteration and deletion slow (but uncommon usecase).

If the last two cases are common, a std::list may be used. Also consider testing a std::vector` since it is more cache efficient.

Iteration in an unordered_map may be slow due to iterating over a large number of unused elements in the hashtable. Insertions will be quich until collision levels become intolerable at which point the whole data structure will need to laid out again.

map s have relatively fast iteration except that data elements may be far apart. Insertion can be slow due to the re-balancing of the red-black trees that this requires.

The main usecase for unordered_maps is for fast lookup (O1). normal map have fastish lookup (O log n) but much better iteration performance.

If you have hard real-time requirements, I would recommend map over unordered_map. std::map has guaranteed performance 100% of the time, but the std::unordered_map may do a rehash and completely ruin real-time performance in some critical corner case. In general, I prefer red-black trees (std::map) over hashtables (std::unordered_map) if I need absolute guarantees on worst-case performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM