The current implementations of __hash_table::find used by std::unordered_set/unordered_map call key_eq on each key that lands in the same bucket as the key you're looking for. However, since equal objects mush hash to the same value, you can short-circuit the possibly expensive call to key_eq by checking the hashes first.
LGTM. I benchmarked the change against different key types and:
- The change doesn't have a large detrimental impact when the key equality is as expensive as hash equality. I benchmarked std::unordered_set<int>.find(...) at 27ns and 29ns before and after the change for a load factor >= 3.5, and 15ns vs 17 ns when the load factor is less than one.
- The change has a large positive impact when the load factor is > 1 and where key equality is more expensive than hash equality. For strings of size 1024 that only differed in the last characters I noticed a change of 880ns to 650ns. for a load factor >= 3.5.
- This change has a slight positive inpact when the load factor is < 1. For the same string inputs (mentioned above) I saw timings of 661ns and 623ns before and after.