diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-03-24 11:18:42 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-03-24 11:18:42 -0300 |
commit | b858161fbcd3992e91c1e555ca7797ec8bec3f84 (patch) | |
tree | 8c885b22a4154af416a4d66bd7b21922065c4357 | |
parent | 80bac182db4bba6fc0dcfdb0d4d6abe4183083d1 (diff) | |
download | lua-b858161fbcd3992e91c1e555ca7797ec8bec3f84.tar.gz lua-b858161fbcd3992e91c1e555ca7797ec8bec3f84.tar.bz2 lua-b858161fbcd3992e91c1e555ca7797ec8bec3f84.zip |
new hash method for lua_Number (double) (due to a performance problem)
-rw-r--r-- | ltable.c | 53 |
1 files changed, 38 insertions, 15 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.129 2003/03/18 12:50:04 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.130 2003/03/20 20:26:33 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -21,6 +21,7 @@ | |||
21 | ** performance penalties. | 21 | ** performance penalties. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <string.h> | ||
24 | 25 | ||
25 | #define ltable_c | 26 | #define ltable_c |
26 | 27 | ||
@@ -54,17 +55,41 @@ | |||
54 | #endif | 55 | #endif |
55 | 56 | ||
56 | 57 | ||
57 | #define hashg(t,n) (gnode(t, lmod((n), sizenode(t)))) | 58 | #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) |
58 | 59 | ||
59 | #define hashnum(t,n) hashg(t, cast(lu_hash, cast(ls_hash, (n)))) | 60 | #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) |
60 | #define hashstr(t,str) hashg(t, (str)->tsv.hash) | 61 | #define hashboolean(t,p) hashpow2(t, p) |
61 | #define hashboolean(t,p) hashg(t, p) | 62 | |
63 | |||
64 | /* | ||
65 | ** for some types, it is better to avoid modulus by power of 2, as | ||
66 | ** they tend to have many 2 factors. | ||
67 | */ | ||
68 | #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) | ||
69 | |||
70 | |||
71 | #define hashpointer(t,p) hashmod(t, IntPoint(p)) | ||
72 | |||
73 | |||
74 | /* | ||
75 | ** number of ints inside a lua_Number | ||
76 | */ | ||
77 | #define numints cast(int, sizeof(lua_Number)/sizeof(int)) | ||
78 | |||
62 | 79 | ||
63 | /* | 80 | /* |
64 | ** avoid modulus by power of 2 for pointers, as they tend to have many | 81 | ** hash for lua_Numbers |
65 | ** 2 factors. | ||
66 | */ | 82 | */ |
67 | #define hashpointer(t,p) (gnode(t, (IntPoint(p) % ((sizenode(t)-1)|1)))) | 83 | static Node *hashnum (const Table *t, lua_Number n) { |
84 | unsigned int a[numints]; | ||
85 | int i; | ||
86 | n += 1; /* normalize number (avoid -0) */ | ||
87 | lua_assert(sizeof(a) <= sizeof(n)); | ||
88 | memcpy(a, &n, sizeof(a)); | ||
89 | for (i = 1; i < numints; i++) a[0] += a[i]; | ||
90 | return hashmod(t, cast(lu_hash, a[0])); | ||
91 | } | ||
92 | |||
68 | 93 | ||
69 | 94 | ||
70 | /* | 95 | /* |
@@ -73,11 +98,8 @@ | |||
73 | */ | 98 | */ |
74 | Node *luaH_mainposition (const Table *t, const TObject *key) { | 99 | Node *luaH_mainposition (const Table *t, const TObject *key) { |
75 | switch (ttype(key)) { | 100 | switch (ttype(key)) { |
76 | case LUA_TNUMBER: { | 101 | case LUA_TNUMBER: |
77 | int ikey; | 102 | return hashnum(t, nvalue(key)); |
78 | lua_number2int(ikey, nvalue(key)); | ||
79 | return hashnum(t, ikey); | ||
80 | } | ||
81 | case LUA_TSTRING: | 103 | case LUA_TSTRING: |
82 | return hashstr(t, tsvalue(key)); | 104 | return hashstr(t, tsvalue(key)); |
83 | case LUA_TBOOLEAN: | 105 | case LUA_TBOOLEAN: |
@@ -416,9 +438,10 @@ const TObject *luaH_getnum (Table *t, int key) { | |||
416 | if (1 <= key && key <= t->sizearray) | 438 | if (1 <= key && key <= t->sizearray) |
417 | return &t->array[key-1]; | 439 | return &t->array[key-1]; |
418 | else { | 440 | else { |
419 | Node *n = hashnum(t, key); | 441 | lua_Number nk = cast(lua_Number, key); |
442 | Node *n = hashnum(t, nk); | ||
420 | do { /* check whether `key' is somewhere in the chain */ | 443 | do { /* check whether `key' is somewhere in the chain */ |
421 | if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == (lua_Number)key) | 444 | if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk) |
422 | return gval(n); /* that's it */ | 445 | return gval(n); /* that's it */ |
423 | else n = n->next; | 446 | else n = n->next; |
424 | } while (n); | 447 | } while (n); |