From c1b75f5ff0460274229801816265a0efe5731b3a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 May 2023 12:53:17 -0600 Subject: [PATCH] [map] Speedup for int types Since our int hash is now good, we don't need the modulo prime here, so forgo it. Major speedup: Comparing before to after Benchmark Time CPU Time Old Time New CPU Old CPU New ------------------------------------------------------------------------------------------------------------------- BM_MapInsert/16 -0.4136 -0.4137 6 4 6 4 BM_MapInsert/64 -0.4442 -0.4441 6 3 6 3 BM_MapInsert/512 -0.5382 -0.5383 8 4 8 4 BM_MapInsert/4096 -0.4160 -0.4162 8 5 8 5 BM_MapInsert/32768 -0.3256 -0.3258 12 8 12 8 BM_MapInsert/262144 -0.1723 -0.1727 11 10 11 9 BM_MapInsert/1048576 -0.2310 -0.2309 28 22 28 22 BM_MapLookup/16 -0.0247 -0.0247 3 3 3 3 BM_MapLookup/64 -0.1039 -0.1038 3 3 3 3 BM_MapLookup/512 -0.1076 -0.1079 4 3 4 3 BM_MapLookup/4096 -0.3729 -0.3732 9 6 9 6 BM_MapLookup/32768 +0.2467 +0.2468 9 12 9 12 BM_MapLookup/262144 -0.1862 -0.1868 14 11 14 11 BM_MapLookup/1048576 +0.1159 +0.1160 15 17 15 17 OVERALL_GEOMEAN -0.2414 -0.2416 0 0 0 0 --- src/hb-map.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 6063ee29b..b70070a48 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -212,12 +212,12 @@ struct hb_hashmap_t hash &= 0x3FFFFFFF; // We only store lower 30bit of hash unsigned int tombstone = (unsigned int) -1; - unsigned int i = hash % prime; + unsigned int i = std::is_integral::value ? hash & mask : hash % prime; unsigned length = 0; unsigned step = 0; while (items[i].is_used ()) { - if ((hb_is_same (K, hb_codepoint_t) || items[i].hash == hash) && + if ((std::is_integral::value || items[i].hash == hash) && items[i] == key) break; if (items[i].is_tombstone () && tombstone == (unsigned) -1) @@ -295,11 +295,11 @@ struct hb_hashmap_t if (unlikely (!items)) return nullptr; hash &= 0x3FFFFFFF; // We only store lower 30bit of hash - unsigned int i = hash % prime; + unsigned int i = std::is_integral::value ? hash & mask : hash % prime; unsigned step = 0; while (items[i].is_used ()) { - if ((hb_is_same (K, hb_codepoint_t) || items[i].hash == hash) && + if ((std::is_integral::value || items[i].hash == hash) && items[i] == key) { if (items[i].is_real ())