Accidentally Quadratic Rust Hash Tables
I enjoy this bug for at least two reasons: One, it’s fun technically, allowing us to take a brief deep dive into hash-table implementation – something most of us are normally able to treat as a solved problem – and two, it’s a great example of subtle quadratic behavior in a system specifically designed by smart and well-informed developers to avoid the possibility of accidental quadratic behavior!
[…]
Robin Hood hashing improves on linear probing with a simple trick: When you’re scanning forward from H%N, look at each element you encounter. If the inserting element is further from its “natural” bucket than the element in the bucket you’re considering, then swap the new element and the element in that bucket, and continue scanning with the other element.
[…]
Rust’s problem arises when you iterate over one table and insert the resulting entries into another table. The problem occurs because iteration over a hash table [proceeds] by walking the backing array of the hash table directly. This results in yielding entries approximately in hash order, which turns out to be fatal when combined with the other elements of Rust’s [implementation].
Via Alexis Beingessner:
Meanwhile Swift’s Dictionary is just plain old First Come First Serve with Java-style hash codes. Lots of work to do there!
Previously: Exploring Swift Dictionary’s Implementation, Exposing NSDictionary.
Update (2018-04-03): See also: SR-3268.
1 Comment RSS · Twitter
[…] Accidentally Quadratic Rust Hash Tables, Exploring Swift Dictionary’s Implementation, Exposing […]