1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-25 01:37:19 +00:00

Use boost's way of combining hash values for arrays and kv pairs.

`seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);`
from https://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html

The current way of combining hashes peforms poorly on hash values of
numbers. Changing the way hashes are combined canlead to a significant speed up:

```
time janet_new -e '(def tbl @{}) (loop [x :in (range 1000) y :in (range 1000)] (put tbl {0 x 1 y} true))'
3.77s user 0.08s system 99% cpu 3.843 total

time janet_orig -e '(def tbl @{}) (loop [x :in (range 1000) y :in (range 1000)] (put tbl {0 x 1 y} true))'
48.98s user 0.15s system 99% cpu 49.136 total
```
This commit is contained in:
Felix Riedel 2020-12-22 21:51:16 +00:00
parent cae4f19629
commit c76e0ae685

View File

@ -227,19 +227,21 @@ int32_t janet_string_calchash(const uint8_t *str, int32_t len) {
/* Computes hash of an array of values */ /* Computes hash of an array of values */
int32_t janet_array_calchash(const Janet *array, int32_t len) { int32_t janet_array_calchash(const Janet *array, int32_t len) {
const Janet *end = array + len; const Janet *end = array + len;
uint32_t hash = 5381; uint32_t hash = 0;
while (array < end) while (array < end) {
hash = (hash << 5) + hash + janet_hash(*array++); uint32_t elem = janet_hash(*array++);
hash ^= elem + 0x9e3779b9 + (hash<<6) + (hash>>2);
}
return (int32_t) hash; return (int32_t) hash;
} }
/* Computes hash of an array of values */ /* Computes hash of an array of values */
int32_t janet_kv_calchash(const JanetKV *kvs, int32_t len) { int32_t janet_kv_calchash(const JanetKV *kvs, int32_t len) {
const JanetKV *end = kvs + len; const JanetKV *end = kvs + len;
uint32_t hash = 5381; uint32_t hash = 0;
while (kvs < end) { while (kvs < end) {
hash = (hash << 5) + hash + janet_hash(kvs->key); hash ^= janet_hash(kvs->key) + 0x9e3779b9 + (hash<<6) + (hash>>2);
hash = (hash << 5) + hash + janet_hash(kvs->value); hash ^= janet_hash(kvs->value) + 0x9e3779b9 + (hash<<6) + (hash>>2);
kvs++; kvs++;
} }
return (int32_t) hash; return (int32_t) hash;