martinus / unordered_dense

A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion
MIT License
898 stars 72 forks source link

MSVC generated code is bad #4

Closed martinus closed 2 years ago

martinus commented 2 years ago

std::hash is really slow on windows, generates a hell of a lot of imul. Don't fall back to it, until really necessary

martinus commented 2 years ago

Benchmark results:

Linux, clang++ 13.0.1: ankerl::unordered_dense::map ns/op op/s err% ins/op cyc/op IPC bra/op miss% total benchmarking
10,456,378.00 95.64 0.1% 101,029,741.00 33,226,459.00 3.041 25,109,968.00 0.1% 0.12 ankerl::unordered_dense::map<uint64_t, size_t> iterate while adding then removing
128,132,576.00 7.80 0.3% 542,400,290.00 406,468,349.00 1.334 61,729,425.00 12.0% 1.42 ankerl::unordered_dense::map<uint64_t, size_t> random insert erase
138,092,089.00 7.24 0.3% 584,996,547.00 438,560,451.00 1.334 100,922,347.00 6.5% 1.53 ankerl::unordered_dense::map<uint64_t, size_t> 50% probability to find
15,266,999.00 65.50 0.3% 106,432,022.00 48,693,694.00 2.186 25,921,308.00 0.1% 0.18 ankerl::unordered_dense::map<std::string, size_t> iterate while adding then removing
522,252,900.00 1.91 0.8% 2,889,992,573.00 1,656,054,820.00 1.745 352,929,113.00 3.9% 5.77 ankerl::unordered_dense::map<std::string, size_t> random insert erase
398,917,499.00 2.51 0.2% 2,589,100,679.00 1,255,316,510.00 2.063 318,743,586.00 2.1% 4.40 ankerl::unordered_dense::map<std::string, size_t> 50% probability to find
robin_hood::unordered_flat_map ns/op op/s err% ins/op cyc/op IPC bra/op miss% total benchmarking
88,779,774.00 11.26 0.2% 363,295,754.00 282,963,884.00 1.284 52,991,290.00 0.8% 1.00 robin_hood::unordered_flat_map<uint64_t, size_t> iterate while adding then removing
182,156,559.00 5.49 0.1% 648,560,823.00 580,588,757.00 1.117 65,227,482.00 20.0% 2.05 robin_hood::unordered_flat_map<uint64_t, size_t> random insert erase
161,153,746.00 6.21 0.2% 699,766,270.00 511,953,708.00 1.367 73,791,117.00 11.5% 1.81 robin_hood::unordered_flat_map<uint64_t, size_t> 50% probability to find
90,357,941.00 11.07 0.2% 371,978,741.00 288,236,935.00 1.291 54,180,921.00 0.8% 1.01 robin_hood::unordered_flat_map<std::string, size_t> iterate while adding then removing
661,080,369.00 1.51 0.2% 4,210,932,698.00 2,108,445,010.00 1.997 469,336,688.00 2.6% 7.35 robin_hood::unordered_flat_map<std::string, size_t> random insert erase
601,181,881.00 1.66 0.4% 3,838,032,670.00 1,915,156,243.00 2.004 330,429,865.00 2.5% 6.69 robin_hood::unordered_flat_map<std::string, size_t> 50% probability to find
std::unordered_map ns/op op/s err% ins/op cyc/op IPC bra/op miss% total benchmarking
98,298,332.00 10.17 1.0% 102,527,853.00 312,980,521.00 0.328 25,523,728.00 0.1% 1.06 std::unordered_map<uint64_t, size_t> iterate while adding then removing
222,034,779.00 4.50 0.1% 700,586,088.00 708,149,988.00 0.989 132,799,451.00 6.6% 2.47 std::unordered_map<uint64_t, size_t> random insert erase
322,060,122.00 3.11 0.0% 506,422,457.00 1,026,687,249.00 0.493 86,441,657.00 11.8% 3.56 std::unordered_map<uint64_t, size_t> 50% probability to find
332,284,553.00 3.01 0.2% 108,712,711.00 1,059,923,550.00 0.103 26,476,254.00 0.1% 3.67 std::unordered_map<std::string, size_t> iterate while adding then removing
928,712,123.00 1.08 0.1% 4,284,647,292.00 2,962,368,185.00 1.446 578,118,501.00 1.6% 10.24 std::unordered_map<std::string, size_t> random insert erase
1,043,774,629.00 0.96 0.2% 4,269,617,190.00 3,328,972,577.00 1.283 494,180,272.00 2.0% 11.64 std::unordered_map<std::string, size_t> 50% probability to find
martinus commented 2 years ago

Fixed with the hash update in cdf151f02da6721785a3ff3bc6085b428d735582, the problem was that std::hash on windows for numbers is really really slow