C++ map vs unordered_map: Performance, Complexity, and How to Choose

C++ map vs unordered_map: Performance, Complexity, and How to Choose

이 글의 핵심

Deep dive: map vs unordered_map internals, complexity, benchmarks, memory, and selection criteria.

For the abstract hash table model (buckets, collisions, average vs worst case), see hash tables. For Python dict and built-in mapping types alongside C++, see Python data types.

Introduction: “If I replace map with unordered_map, will it get faster?"

"I don’t need sorted order but I used map anyway”

The STL provides std::map (ordered) and std::unordered_map (hashed). Different complexities ⇒ choose for the workload.

std::map<std::string, int> scores;
scores["Alice"] = 100;  // O(log n)

std::unordered_map<std::string, int> fast;
fast["Alice"] = 100;    // average O(1)

This article covers:

  • Internal structures
  • Complexity
  • Example benchmark numbers (illustrative)
  • Memory tradeoffs
  • Decision guidance
  • Custom hashing

Table of contents

  1. Internals
  2. Complexity
  3. Benchmarks
  4. Memory
  5. Selection
  6. Custom keys
  7. Summary

1. Internal structure

map: balanced BST (commonly red-black)

  • Sorted by key
  • Worst-case operations typically O(log n)

unordered_map: hash table

  • Buckets + chaining/open addressing (implementation-defined)
  • Average O(1); worst-case O(n) with bad hashing/adversarial inputs

2. Time complexity

Operationmapunordered_map
Insert/Erase/LookupO(log n)average O(1), worst O(n)
IterationO(n), sorted orderO(n), unspecified order
min/max keyO(log n) begin/rbeginO(n) scan

3. Example benchmark narrative

Illustrative relative results from many blogs/microbenchmarks:

  • Insert 1e6 ints: unordered_map often several× faster than map
  • Lookup heavy: unordered_map often faster on average
  • Iterate: similar order of magnitude
  • Sorted iteration: map is natural; sorting a vector copy from unordered_map costs extra

Always validate on your data, compiler, and -O flags.


4. Memory

Tree nodes vs buckets + per-entry storage: depends on n, key size, implementation. Measure RSS if it matters.


5. Selection guide

Need sorted keys or range queries (lower_bound/upper_bound)?
  Yes -> map
  No  -> consider unordered_map

Worst-case latency guarantees critical?
  Yes -> often map (log n) vs hash worst-case pathologies
ScenarioPrefer
Default fast lookup, no orderunordered_map
Sorted iteration / order statisticsmap
Range search on keysmap
Hard realtime + predictable boundsoften map (depends)

Examples

Word counts: usually unordered_map.

Leaderboard by score: often std::map with custom comparator or sorted container.

Cache: unordered_map + reserve.

Time-series range query: map + lower_bound/upper_bound.


Hash collisions and performance

  • Bad hash ⇒ everything in one bucket ⇒ degrades toward linear scan.
  • Use reserve when you know approximate final size to reduce rehashes.

Custom key types

  • map: operator< or Compare
  • unordered_map: std::hash specialization (or custom hasher) + operator== (or KeyEqual)

Summary

  1. Need order/range queriesmap
  2. Average fast lookup, no orderunordered_map
  3. reserve to reduce rehash churn
  4. Profile instead of guessing

  • Map basics series posts
  • Hashing guide
  • Container selection guide

Keywords

map vs unordered_map, C++ hash map, O(1) vs O(log n), std::unordered_map reserve


... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3