lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 26/06/2011 14:05, Rebel Neurofog wrote:
But that takes a table lookup for the key...
I'm not sure, but it is probably faster than sequential string
comparison (especially for lots of strings).
But of course it is slower than hashing.
It's kind of simple intermediate workaround.

There's also another trick (which works fast for single Lua state per
executable):

static const char *points_string;

static void func ()
{
     lua_State *L = lua_newstate (...);

     lua_pushliteral (L, "points"); /* There is a simpler way in Lua 5.2 */
     points_string = lua_tostring (L, -1);
     lua_setfield (L, LUA_REGISTRYINDEX, "points_string"); /* to
prevent garbage collection */
}

static void some_lua_func (lua_State *L)
{
     const char *st = lua_tostring (L, 1);
     if (points_string == st) { /* That's the magic */
         /* We've got a match here */
     }
     return 0;
}

If you have several Lua states, then you may do something like that:

typedef struct some_ud_t {
     const char *points_string;
} some_ud_t;

static void func ()
{
     some_ud_t *ud = malloc (sizeof (some_ud_t));
     lua_State *L = lua_newstate (allocator, ud);

     lua_pushliteral (L, "points"); /* There is a simpler way in Lua 5.2 */
     ud->points_string = lua_tostring (L, -1);
     lua_setfield (L, LUA_REGISTRYINDEX, "points_string"); /* to
prevent garbage collection */
}

static void some_lua_func (lua_State *L)
{
     some_ud_t *ud;
     lua_getallocf (L,&ud);
     const char *st = lua_tostring (L, 1);
     if (ud->points_string == st) { /* That's the magic */
         /* We've got a match here */
     }
     return 0;
}

Once again, I didn't test all these mad things

But then I'd have to convert my switch to a series of ifs since the pointers to the literals are computed during runtime.

I know switches are not great with sparse constant spaces such as when using hashes (i.e. only a few tenths of used values from 2^32 possible values) but I like the compiler doing the binary search for me (gcc does) instead of having to figure it out myself. I'm also experimenting hashing the hash (just shifts and xors, nothing fancy or costly) to make the space dense enough so the switch will (hopefully) become a goto table + one if for each case to see if it's really a match. Better than the hard-coded binary tree...

Cheers,

Andre