Choosing a Container for Lookup
The cost of a map lookup is $O(\log(n))$, where n is the number of elements, and the source notes that a map with 1,000,000 elements needs only about 20 comparisons and indirections.
A Lookup You Already Rely On
Suppose you already store your data in a map and you ask it to find one element. How much work does that search take? The answer depends on the container you chose, and choosing well is what this article is about. The source answers the question for a map directly: the cost of a map lookup is $O(\log(n))$, where $n$ is the number of elements in the map. The source calls this pretty good. The rest of this article explains why it is good, and when a different kind of container can do better.
What do you think happens?
A map holds 1,000,000 elements. Roughly how many comparisons and indirections does one lookup need?
Reveal answer
About 20
The source gives this figure directly: a map with 1,000,000 elements needs only about 20 comparisons and indirections to find an element. The map does not inspect a million entries.
Following a Map Lookup Step by Step
A map finds elements by comparison. It uses an ordering function, such as the less-than operator, to decide which way to move as it searches. At each step, the map compares the key it is looking for against an element it has reached, and the result of that comparison tells it where the element must be if it exists at all. Its search is therefore a sequence of decisions, each one narrowing the set of places that could still hold the answer.
Read the picture below from top to bottom. Each step starts with a candidate set of elements and ends with a smaller one. The number on each node is the count of candidates still in play. The diagram shows the idea of repeated narrowing: the search space shrinks at every comparison, so the number of steps needed is far smaller than the number of elements.
What the Logarithm Means in Practice
A cost written as $O(\log(n))$ grows with the size of the collection, but much more slowly than the size itself. The source makes this concrete with a single example: for a map with 1,000,000 elements, one lookup performs only about 20 comparisons and indirections. The logarithm is the reason the number stays small. Each comparison eliminates a large share of the remaining candidates, so the count of steps rises only as the logarithm of the element count. In the source's example, $\log_2(1{,}000{,}000)$ is about 20, which matches the stated figure.
| Elements in the map (n) | Approximate steps for a map lookup, $\log_2(n)$ |
|---|---|
| 1,000 | about 10 |
| 1,000,000 | about 20 |
| 1,000,000,000 | about 30 |
Growth of a logarithmic lookup. The step counts are the base-2 logarithm of n, rounded, so each thousandfold increase in n adds only about 10 steps.
Estimating the cost of a larger map
A map grows from 1,000,000 elements to 1,000,000,000 elements, a thousandfold increase. How many more comparisons per lookup does a logarithmic map lookup need?
- 1Identify the cost
A map lookup costs $O(\log(n))$, so the step count is governed by the logarithm of n, not by n itself.
- 2Count the steps at the first size
For n = 1,000,000, $\
log_2(1{,}000{,}000)$ is about 20, matching the source's figure. - 3Count the steps at the second size
For n = 1,000,000,000, $\
log_2(1{,}000{,}000{,}000)$ is about 30. - 4Compare the change
The collection grew a thousandfold, but the lookup needs only about 10 more steps.
A thousandfold growth in the map adds only about 10 comparisons per lookup. The work grows far more slowly than the collection, which is why logarithmic lookup suits large maps.
Taking a Hashed Route Instead
The two containers differ in the route a lookup takes. Both routes start from a key and end at an element, but the middle step is different. A map's route passes through comparisons against an ordering, which is why its cost is logarithmic. A hashed lookup avoids comparison using an ordering function. The source states that in many cases we can do better by using a hashed lookup instead, so this is the central idea of the article: the map's cost comes from relying on ordering, and a hashed route takes a different path that can beat that cost in many situations.
Notice what the diagram does not show. The source does not describe how a hashed container arranges its elements internally, so the comparison here focuses only on the lookup route. One container searches by comparing against an ordering, and the other avoids that ordering requirement entirely. Do not read the hashed route as a guarantee: the source calls the faster result a tendency, not a promise.
Why Unordered Does Not Mean Messy
The standard-library hashed containers are called unordered because they do not require an ordering function. The name describes a requirement, not a messy or random layout. A map needs an ordering function such as the less-than operator to decide how its elements relate and how to search them. An unordered_map does not need that ordering function at all, so the name points to the absence of that requirement rather than to some disorder that a programmer must cope with.
Mistakes Beginners Make with Lookup Containers
Common mistake Assuming a map lookup is slow because it is a comparison-based search
Why it failsThe source calls the $O(\log(n))$ cost pretty good, and a map of 1,000,000 elements needs only about 20 comparisons and indirections.
Do this insteadJudge the cost by its growth rate. A logarithmic lookup stays cheap even as the collection becomes large.
Common mistake Believing that unordered_map is always faster than map
Why it failsThe source says
unordered_mapprovides faster lookup than a map in many cases, but this is a tendency and not a guarantee.Do this insteadTreat the hashed container as a strong candidate for lookup, and confirm the choice against the actual workload when speed matters.
Common mistake Reading unordered as meaning the elements are stored randomly and cannot be handled
Why it failsThe name refers to the absence of a required ordering function, not to disorder in the container.
Do this insteadRemember that unordered describes a requirement the container does not impose, so it does not imply chaos.
Common mistake Choosing a hashed container because it sounds more advanced, without first stating what the code needs from the container
Deciding Between Ordered and Hashed Lookup
The source gives a clear decision rule. If the goal is efficient lookup, consider a hashed lookup as an alternative to comparison using an ordering function, since it can be better in many cases. A hashed container is a reasonable choice when your main operation is finding an element by its key. A map remains the right tool when the ordering itself matters to your program, because a map uses an ordering function to decide how its elements relate. The source's own description of unordered containers, that they do not require an ordering function, is the test: if your code needs no ordering, the unordered route is available to you.
Checking a Container Choice
Your program stores product records keyed by product ID. Its most frequent operation is looking up one product by ID. Occasionally it must print all product IDs in sorted order. Which container would you consider for the lookups, and what does the sorted-printing requirement tell you about the choice?
Hints
- Ask which operation dominates the workload: single-key lookup or ordered traversal.
- Recall that an
unordered_mapdoes not require an ordering function, and the source does not describe any traversal order for it. - Consider whether a map's use of an ordering function is something your code needs.
Key Takeaways
- A map lookup costs $O(\log(n))$, so the step count grows far more slowly than the number of elements; a map of 1,000,000 elements needs about 20 comparisons and indirections.
- A map searches by comparison using an ordering function such as the less-than operator, while a hashed lookup avoids that comparison and can be faster in many cases, though not guaranteed.
- The standard-library hashed containers are called unordered because they do not require an ordering function, not because their contents are disordered.
- Choose
unordered_mapwhen the work is mainly fast lookup by key and the code does not depend on an ordering of the elements; choose a map when that ordering matters.