summaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-10-12 00:58:07 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-10-12 00:58:07 -0700
commite9b6b4c8e91025469e8fedcd1498da4227f30879 (patch)
tree166c259bd1ea1940104e9d7edeb72157b8d73289 /hash.c
parentede1079e13ac0cbdcc63738f8a3414fefaa0c48d (diff)
downloadtxr-e9b6b4c8e91025469e8fedcd1498da4227f30879.tar.gz
txr-e9b6b4c8e91025469e8fedcd1498da4227f30879.tar.bz2
txr-e9b6b4c8e91025469e8fedcd1498da4227f30879.zip
hash: optimize vector access.
We use direct access instead of going through vecref/vecref_l. As a result of this change, I measured an 8% speedup in "make retest"! I'm also seeing a more than 10% speedup in "make" after "make clean-tlo" (i.e. recompiling the Lisp library). * hash.c (hash_mark, hash_grow, copy_hash, gethash_c, gethash_e, remhash, hash_next, hash_peek, do_weak_tables): Access the table directly.
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/hash.c b/hash.c
index 57b029de..22532e5b 100644
--- a/hash.c
+++ b/hash.c
@@ -593,8 +593,7 @@ static void hash_mark(val hash)
case hash_weak_keys:
/* Keys are weak: mark the values only. */
for (i = 0; i < h->modulus; i++) {
- val ind = num_fast(i);
- val chain = vecref(h->table, ind);
+ val chain = h->table->v.vec[i];
val iter;
for (iter = chain; iter != nil; iter = us_cdr(iter)) {
@@ -609,8 +608,7 @@ static void hash_mark(val hash)
/* Values are weak: mark the keys only. */
for (i = 0; i < h->modulus; i++) {
- val ind = num_fast(i);
- val chain = vecref(h->table, ind);
+ val chain = h->table->v.vec[i];
val iter;
for (iter = chain; iter != nil; iter = us_cdr(iter)) {
@@ -647,13 +645,13 @@ static void hash_grow(struct hash *h, val hash)
new_table = vector(num_fast(new_modulus), nil);
for (i = 0; i < h->modulus; i++) {
- val conses = vecref(h->table, num_fast(i));
+ val conses = h->table->v.vec[i];
while (conses) {
val entry = us_car(conses);
val next = us_cdr(conses);
- loc pchain = vecref_l(new_table,
- num_fast(entry->ch.hash % new_modulus));
+ loc pchain = mkloc(new_table->v.vec[entry->ch.hash % new_modulus],
+ new_table);
us_rplacd(conses, deref(pchain));
set(pchain, conses);
conses = next;
@@ -869,9 +867,9 @@ val copy_hash(val existing)
struct hash *ex = coerce(struct hash *, cobj_handle(self, existing, hash_s));
struct hash *h = coerce(struct hash *, chk_malloc(sizeof *h));
val mod = num_fast(ex->modulus);
- val table = vector(mod, nil);
val hash = cobj(coerce(mem_t *, h), hash_s, &hash_ops);
- val iter;
+ val table = vector(mod, nil);
+ cnum i;
h->modulus = ex->modulus;
h->count = ex->count;
@@ -883,8 +881,9 @@ val copy_hash(val existing)
h->usecount = 0;
h->hops = ex->hops;
- for (iter = zero; lt(iter, mod); iter = plus(iter, one))
- set(vecref_l(h->table, iter), copy_hash_chain(vecref(ex->table, iter)));
+ for (i = 0; i < h->modulus; i++)
+ set(mkloc(h->table->v.vec[i], h->table),
+ copy_hash_chain(ex->table->v.vec[i]));
return hash;
}
@@ -894,7 +893,7 @@ val gethash_c(val self, val hash, val key, loc new_p)
struct hash *h = coerce(struct hash *, cobj_handle(self, hash, hash_s));
int lim = hash_rec_limit;
ucnum hv = h->hops->hash_fun(key, &lim, h->seed);
- loc pchain = vecref_l(h->table, num_fast(hv % h->modulus));
+ loc pchain = mkloc(h->table->v.vec[hv % h->modulus], h->table);
val old = deref(pchain);
val cell = h->hops->acons_new_c_fun(key, hv, new_p, pchain);
if (old != deref(pchain) && ++h->count > 2 * h->modulus && h->usecount == 0)
@@ -907,7 +906,7 @@ val gethash_e(val self, val hash, val key)
struct hash *h = coerce(struct hash *, cobj_handle(self, hash, hash_s));
int lim = hash_rec_limit;
ucnum hv = h->hops->hash_fun(key, &lim, h->seed);
- val chain = vecref(h->table, num_fast(hv % h->modulus));
+ val chain = h->table->v.vec[hv % h->modulus];
return h->hops->assoc_fun(key, hv, chain);
}
@@ -961,7 +960,7 @@ val remhash(val hash, val key)
struct hash *h = coerce(struct hash *, cobj_handle(self, hash, hash_s));
int lim = hash_rec_limit;
ucnum hv = h->hops->hash_fun(key, &lim, h->seed);
- val *pchain = valptr(vecref_l(h->table, num_fast(hv % h->modulus)));
+ val *pchain = &h->table->v.vec[hv % h->modulus];
val existing = h->hops->assoc_fun(key, hv, *pchain);
if (existing) {
@@ -1078,7 +1077,7 @@ val hash_next(val iter)
h->usecount--;
return nil;
}
- set(mkloc(hi->cons, iter), vecref(h->table, num_fast(hi->chain)));
+ set(mkloc(hi->cons, iter), h->table->v.vec[hi->chain]);
}
return us_car(hi->cons);
}
@@ -1103,7 +1102,7 @@ val hash_peek(val iter)
do {
if (++chain >= h->modulus)
return nil;
- cell = vecref(h->table, num_fast(chain));
+ cell = h->table->v.vec[chain];
} while (!cell);
return us_car(cell);
}
@@ -1155,8 +1154,7 @@ static void do_weak_tables(void)
/* Sweep through all entries. Delete any which have keys
that are garbage. */
for (i = 0; i < h->modulus; i++) {
- val ind = num_fast(i);
- val *pchain = valptr(vecref_l(h->table, ind));
+ val *pchain = &h->table->v.vec[i];
val *iter;
for (iter = pchain; !gc_is_reachable(*iter); ) {
@@ -1179,8 +1177,7 @@ static void do_weak_tables(void)
/* Sweep through all entries. Delete any which have values
that are garbage. */
for (i = 0; i < h->modulus; i++) {
- val ind = num_fast(i);
- val *pchain = valptr(vecref_l(h->table, ind));
+ val *pchain = &h->table->v.vec[i];
val *iter;
for (iter = pchain; !gc_is_reachable(*iter); ) {
@@ -1203,8 +1200,7 @@ static void do_weak_tables(void)
/* Sweep through all entries. Delete any which have keys
or values that are garbage. */
for (i = 0; i < h->modulus; i++) {
- val ind = num_fast(i);
- val *pchain = valptr(vecref_l(h->table, ind));
+ val *pchain = &h->table->v.vec[i];
val *iter;
for (iter = pchain; !gc_is_reachable(*iter); ) {