mirror of
https://github.com/janet-lang/janet
synced 2025-01-26 07:06:51 +00:00
Add some more changes to hashing to improve pointer hashing.
This commit is contained in:
parent
92fdd07ca3
commit
6d9286a202
@ -325,7 +325,7 @@ int32_t janet_hash(Janet x) {
|
|||||||
uint32_t lo = (uint32_t)(as.u & 0xFFFFFFFF);
|
uint32_t lo = (uint32_t)(as.u & 0xFFFFFFFF);
|
||||||
uint32_t hi = (uint32_t)(as.u >> 32);
|
uint32_t hi = (uint32_t)(as.u >> 32);
|
||||||
uint32_t hilo = (hi ^ lo) * 2654435769u;
|
uint32_t hilo = (hi ^ lo) * 2654435769u;
|
||||||
hash = (int32_t)((hilo << 16) | ((hilo >> 16) & 0xFFFF));
|
hash = (int32_t)((hilo << 16) | (hilo >> 16));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JANET_ABSTRACT: {
|
case JANET_ABSTRACT: {
|
||||||
@ -339,15 +339,17 @@ int32_t janet_hash(Janet x) {
|
|||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
default:
|
default:
|
||||||
if (sizeof(double) == sizeof(void *)) {
|
if (sizeof(double) == sizeof(void *)) {
|
||||||
/* Assuming 8 byte pointer */
|
/* Assuming 8 byte pointer (8 byte aligned) */
|
||||||
uint64_t i = janet_u64(x);
|
uint64_t i = janet_u64(x);
|
||||||
uint32_t lo = (uint32_t)(i & 0xFFFFFFFF);
|
uint32_t lo = (uint32_t)(i & 0xFFFFFFFF);
|
||||||
uint32_t hi = (uint32_t)(i >> 32);
|
uint32_t hi = (uint32_t)(i >> 32);
|
||||||
hash = (int32_t)(hi ^ (lo >> 3));
|
uint32_t hilo = (hi ^ lo) * 2654435769u;
|
||||||
|
hash = (int32_t)((hilo << 16) | (hilo >> 16));
|
||||||
} else {
|
} else {
|
||||||
/* Assuming 4 byte pointer (or smaller) */
|
/* Assuming 4 byte pointer (or smaller) */
|
||||||
hash = (int32_t)((char *)janet_unwrap_pointer(x) - (char *)0);
|
ptrdiff_t diff = ((char *)janet_unwrap_pointer(x) - (char *)0);
|
||||||
hash >>= 2;
|
uint32_t hilo = (uint32_t) diff * 2654435769u;
|
||||||
|
hash = (int32_t)((hilo << 16) | (hilo >> 16));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
24
tools/hashbench/ints1.janet
Normal file
24
tools/hashbench/ints1.janet
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
(def f @{})
|
||||||
|
(var collisions 0)
|
||||||
|
(loop [x :range [0 300] y :range [0 300]]
|
||||||
|
(def key (hash (+ (* x 1000) y)))
|
||||||
|
(if (in f key)
|
||||||
|
(++ collisions))
|
||||||
|
(put f key true))
|
||||||
|
(print "ints 1 collisions: " collisions)
|
||||||
|
|
||||||
|
(def f @{})
|
||||||
|
(var collisions 0)
|
||||||
|
(loop [x :range [100000 101000] y :range [100000 101000]]
|
||||||
|
(def key (hash [x y]))
|
||||||
|
(if (in f key) (++ collisions))
|
||||||
|
(put f key true))
|
||||||
|
(print "int pair 1 collisions: " collisions)
|
||||||
|
|
||||||
|
(def f @{})
|
||||||
|
(var collisions 0)
|
||||||
|
(loop [x :range [10000 11000] y :range [10000 11000]]
|
||||||
|
(def key (hash [x y]))
|
||||||
|
(if (in f key) (++ collisions))
|
||||||
|
(put f key true))
|
||||||
|
(print "int pair 2 collisions: " collisions)
|
Loading…
Reference in New Issue
Block a user