# How does hash table search scales with number of keys?

Say, I have one of the standard implementations of a hash table: chaining or open addressing, and my hash key is a pair of strings. Instead of using the hash table with the pair as a key, I can use the first key to get to a "sub" - hash table, and then use the second key to find the element from it.

How do these strategies compare, e.g. if one assumes the key pairs are more or less uniform?

• Note, if there are $n$ distinct keys they need to be at least $\log n$ bits long on average so simply hashing would take $\theta(\log n)$ time. In fact $\log n$ is optimal for search tables. Nesting hash tables, using distinct subsets of the bits, should also be $\log n$. For most tasks nesting is unnecessary but there are probably specialized cases where it helps. Aug 23 '18 at 18:10

In principle, they're similar in running time and space complexity.

In practice, the first one might have some modest advantages: possibly half as many accesses, less space overhead if some of the "secondary hashtables" were small (e.g., for a particular value of the first key, there aren't many possible second keys).

I would not expect to see a tremendous difference between the two, nor a difference in asymptotic worst-case running time. Both have $O(1)$ expected running time for all major hash table operations, under some reasonable assumptions.

• Interesting, because in all the cases I saw, the second one (hash table of a hash table) was considerably faster. Aug 22 '18 at 14:32
• @LazyCat, Huh. Well, real data (from performance measurements) beats out speculation (my answer) any day. So, I can't explain why you're seeing that. It's not what I would have expected or predicted, but apparently there was something wrong with my expectation. Sorry this wasn't more helpful.
– D.W.
Aug 22 '18 at 14:33
• Np, I'm just hoping there's an easy back of the envelope computation how the complexity scales as we introduce more buckets. Aug 22 '18 at 14:49
• @LazyCat hashtable mapping to hashtable has a best case when the first key is badly distributed and the second key is complementary to it (it's well distributed where the first key is not). However a good mixing function will have the same effect. Aug 22 '18 at 15:01

A well tuned hashtable (in terms of when you grow the table and collision handling) with a good key distribution will stay constant time.

If the second level is a lot faster than the top level it may be worth adding it.

For example Google uses a hashtable that uses open addressing and hold 1 byte of hashkey per element. Using SIMD you can check 16 bytes (or more depending on the SIMD instruction set) against part of the key in a single operation and also check whether you need to move to the next chunk of 16 elements.

But if you are just going to use the same implementation for the second level you are not going to win anything.

How large are your secondary tables? Depending on your data, the secondary tables might have on average not much more than one element. Some implementations don’t bother doing any hashing for small numbers of elements, say up to three. Just store them in a small array. This may be a lot more efficient than a full blown hash table.

How much hashing do you need to do? You may have one key that is in practice close to unique, and the faster hashing may outweigh any disadvantages.