4 ms·
Cuckoo hashing is not only optimal in theory, it is also very fast in practice. The only downside, though, is that the insert time has linear-time worst case. T
by ot 16y ago
Cuckoo hashing is not only optimal in theory, it is also very fast in practice. The only downside, though, is that the insert time has linear-time worst case. Thus it may be not the best solution if latency is an issue.
- jemfinch 16y ago"Linear-time worst case" is different from "amortized constant time", which is what cuckoo hashing provides. Almost all the containers we use on a regular basis provide only amortized constant time inserts.
- jules 16y agoLinear time worst case and amortized constant time are not mutually exclusive. You are right that most containers that we use have amortized constant time complexity, but they also have linear worst case complexity. Most times this is because an internal array has to be resized and the contents have to be copied over to the new enlarged array.
- jemfinch 16y agoNo, they're not mutually exclusive. But what actually matters in most software is "amortized constant time": linear time worst case only matters in hard real-time systems which can't tolerate any deviation from the expected runtime. Even algorithms like binary trees can end up with very bad worst cases unless great care is taken in allocating their nodes.
- ot 16y agoThe linear time behavior of cuckoo hashing is not triggered only when the table has to be enlarged, like standard containers (say, std::vector or python list): a linear numbers of keys can be "cuckooed" out of their slots for an insertion even when the load factor is under the capacity threshold. In standard containers if you pre-define the capacity (say with std::vector::reserve) all the insertions are guaranteed to be constant time. Cuckoo hashing can't give this guarantee.
- pmjordan 16y agoI'm unaware of any hash table implementations which successfully insert elements in absolute constant time in the event of collisions.
- ot 16y agoChained hash tables have constant time insertion, but I'm not sure about the amortized lookup time (the worst case is linear)
- pmjordan 16y agoChaining requires a memory allocation and list insertion on collisions - is it fair to call that absolute constant time? Probability of this happening depends on the number of elements in the container.
- silentbicycle 16y agoPooling memory for allocating links turns the allocation into amortized constant time. List insertion is O(1) if you insert it at the head, and while moving the most-recently-accessed link to the head of the chain doesn't change the worst case behavior, it greatly improves the average in practice (and is dead easy).
- ot 16y agoAs silentbycicle said, list insertion at the head is constant time. About allocation, I agree with you that it is "slow", but all reasonable computation models count a memory allocation as a constant time operation. If we want to go down that road and measure also memory operations, even random memory access would not be worst-case constant time: the MMU has to map the page to the physical location, and this is usually a logarithmic or amortized constant time operation.
- silentbicycle 16y agoYeah, allocation is usually included in the constant factors. Keep them in mind, though - things like locality can have a big impact.
- arnoldoMuller 16y agoThere was a talk around where they were using two replacements at most(or two hash tables), and two hash functions. At insert time you add the object to the first hash table, if there is an object in the bucket, you then try with the second hash table. If you follow this approach a very large percentage of the buckets is going to be full. The remaining objects set (those that cannot be inserted in the first two hash tables because the buckets are full) is so small that you can keep them in a list or in a "standard" hash table. At some point I had a secondary storage implementation of this approach and it was good indeed.
- deleted 16y ago[deleted]