Earlier quoted context omitted.
Yes, but it's also important to understand what you lose when using these better-performing hashtables. First thing that comes to mind is that when performing a successful lookup on a std::unordered_map, the reference is guarrantied to be valid until either (a) you erase that element or (b) the table itself is destroyed. Almost all faster hashtables around give up that properties for better lookup performance. Any in…
Yes, I agree with you that unordered_map should be slower. For context, the author shows off a graph where his custom Fibonacci implementation is the fastest, which proves nothing about Fibonacci hashing.
Fibonacci Hashing: The Optimization That the World Forgot
51–60 of 79 posts
Re: Fibonacci Hashing: The Optimization That the World Forgot
#52Don't do this. Use a real hash function that guarantees a highly random distribution, make your hash tables power-of-two sized, and map from hash value to table index using (hash & (size-1)). The fibonacci constant thing will help clean up the distribution of a bad hash function, but it does nothing for collision resistance if the underlying hash function is weak. -Austin, author of Murmurhash and SMHasher
Wait, I thought the author was saying to use this _after_ using a more secure hash function, not instead of it. Why wouldn't you do that?
Is security even an issue in hash functions for this purpose? I honestly don't know, it's not obvious to me that it is.
Re: Fibonacci Hashing: The Optimization That the World Forgot
#53Earlier quoted context omitted.
Also, there is nothing magic about his fibonacci constant. Any large odd constant with roughly half the bits set at random will do the same thing.
I also did not follow what is special about 2^n/phi. I found this more concise justification: http://mathforum.org/kb/message.jspa?messageID=431065 "Knuth's finding was that the dispersion of indexes for a sequence of consecutive keys is maximized when M is chosen this way, thus a multiplicative hash table with a dense set of keys will have the fewest possible collisions when M approx= 2^N * R." Although, if the keys…
The Golden Ratio (why it is so irrational) - Numberphile https://www.youtube.com/watch?v=sj8Sg8qnjOg
Re: Fibonacci Hashing: The Optimization That the World Forgot
#54Don't do this. Use a real hash function that guarantees a highly random distribution, make your hash tables power-of-two sized, and map from hash value to table index using (hash & (size-1)). The fibonacci constant thing will help clean up the distribution of a bad hash function, but it does nothing for collision resistance if the underlying hash function is weak. -Austin, author of Murmurhash and SMHasher
He's clearly, and obviously not talking about using it as a hash, or even to consider it as a secondary hash as someone mentioned. The use case according to the article is strictly to replace integer modulo to map into buckets for cases where that operation is the limiting factor. In his case that's when 9ns per key is too much, and roughly 1ns is good. For small hash tables sometimes the worst case of a linear scan…
> 1. Hash the key > 2. Map the hash value to a slot
> Knuth [Fibonacci Hash] uses the term “hash function” to refer to something that does both step 1 and step 2.
Re: Fibonacci Hashing: The Optimization That the World Forgot
#55Don't do this. Use a real hash function that guarantees a highly random distribution, make your hash tables power-of-two sized, and map from hash value to table index using (hash & (size-1)). The fibonacci constant thing will help clean up the distribution of a bad hash function, but it does nothing for collision resistance if the underlying hash function is weak. -Austin, author of Murmurhash and SMHasher
He's clearly, and obviously not talking about using it as a hash, or even to consider it as a secondary hash as someone mentioned. The use case according to the article is strictly to replace integer modulo to map into buckets for cases where that operation is the limiting factor. In his case that's when 9ns per key is too much, and roughly 1ns is good. For small hash tables sometimes the worst case of a linear scan…
Re: Fibonacci Hashing: The Optimization That the World Forgot
#56Moral of the story: Always always consult Knuth.
Unless Knuth is outdated. With hash tables Knuth is seriously outdated. With hash functions you can consult his test functions, but he is also outdated. E.g. the CRC scheme is the fastest by far (one even exists in HW), but too easily attackable. Trivial really, any 10 year old can do that, due to some unfortunate CRC properties.
In another comment you write:
> You can easily brute-force even the worst of all siphash in under 4min.
Can you please write what you mean by those statements? Is it about the "hash-flooding DoS" attacks or something else? Can you share a little more of your insights?
Re: Fibonacci Hashing: The Optimization That the World Forgot
#57Earlier quoted context omitted.
The article presents Fibonacci hashing as an operation to map a hash code into a smaller range, but it isn't that, really. The operation that does that is still just taking some bits from the hash code. What Fibonacci hashing actually is is a way of stirring a hash code before use, to spread its entropy out more, so that the bits you end up taking a more likely to be well-distributed. If your hash codes are already w…
> LLVM's libc++ Great find! So the library solutions are still often suboptimal, and it's even more easy to hide bad decisions in the C++ sources, so whoever has the approach "just use the default library" should be aware of that once the performance is important. Yes, even the simple multiplicative constants can significantly improve the hash if it by default doesn't do anything with the input! The libraries definit…
It's also the default hasher in Rust.
Rust's hashing is interesting. Types that want to be hashable implement the Hash trait. What the Hash trait requires is that a type knows how to feed its fields to a Hasher, as a sequence of primitives - it doesn't require that it actually computes a hash itself. It's the Hasher which computes the hash. This is nice, because it's very easy to implement Hash; indeed, so easy that it can be done automatically using a derive macro. The downside is that it's not possible for a type to implement a custom hash that takes particular advantage of its own structure, and so to get a particularly good tradeoff of distribution against performance. The only place to make that tradeoff is in the choice of Hasher, where it has to be made generically across all types.
That said, you can choose the hasher used for individual HashMaps, so if you have a HashMap where you know the keys are integers, you can use a Hasher which just does a Fibonacci hash.
Re: Fibonacci Hashing: The Optimization That the World Forgot
#58Don't do this. Use a real hash function that guarantees a highly random distribution, make your hash tables power-of-two sized, and map from hash value to table index using (hash & (size-1)). The fibonacci constant thing will help clean up the distribution of a bad hash function, but it does nothing for collision resistance if the underlying hash function is weak. -Austin, author of Murmurhash and SMHasher
Also, there is nothing magic about his fibonacci constant. Any large odd constant with roughly half the bits set at random will do the same thing.
You can use it to generate a nice sequence of different colours - set the hue to (n * the golden ratio) mod 1.
But I don't know if that property is really necessary for a hash table. I guess only if you are using a terrible key hash.
Re: Fibonacci Hashing: The Optimization That the World Forgot
#59Moral of the story: Always always consult Knuth.
Unless Knuth is outdated. With hash tables Knuth is seriously outdated. With hash functions you can consult his test functions, but he is also outdated. E.g. the CRC scheme is the fastest by far (one even exists in HW), but too easily attackable. Trivial really, any 10 year old can do that, due to some unfortunate CRC properties.
Is this kind of hyperbole really necessary?
Re: Fibonacci Hashing: The Optimization That the World Forgot
#60Earlier quoted context omitted.
He's clearly, and obviously not talking about using it as a hash, or even to consider it as a secondary hash as someone mentioned. The use case according to the article is strictly to replace integer modulo to map into buckets for cases where that operation is the limiting factor. In his case that's when 9ns per key is too much, and roughly 1ns is good. For small hash tables sometimes the worst case of a linear scan…
He is talking about using it as a hash function and clearly states so. To quote: > 1. Hash the key > 2. Map the hash value to a slot > Knuth [Fibonacci Hash] uses the term “hash function” to refer to something that does both step 1 and step 2.
He is writing from the context of writing a hash table library where the user is expected to provide their own hashing function.