lua-users home
lua-l archive

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

The issue with the pointer comparison is that Lua might at some point in the
future have a compacting garbage collector and the promises or lack thereof
in the API allow for that.

A more likely shift that would cause problems would be the introduction of
short string support as Mike Pall outlined here a while ago. This stores
short strings in line which is potentially a win for a lot of things
including GC performance since it results in fewer pointers to trace during
the mark phase and fewer heap objects to sweep.

Some options to consider:

1. Since Lua doesn't have a compacting collector or short strings now,
ignore the issue and exploit the fact that things don't move. Just be
prepared to adapt if the situation should ever change.

2. Use a separate Lua state (allocated as a thread off the main state) to
accumulate strings that you don't want to move. The APIs do promise that
pointers to strings will stay valid so long as the string is on the stack.
This would still have trouble with short strings, however, because the API
doesn't guarantee uniqueness for the pointer to a string.

3. Look at ways of making pushing the comparison string faster. For example,
if you have a constant C string, you could store them in the registry keyed
by the constant address by implementing something like the following:

    void pushConstantString( lua_State* L, const char* s, size_t len ) {
        lua_pushlightuserdata( L, s );
        lua_rawget( L, LUA_REGISTRYINDEX );
        if( lua_isnil( L, -1 ) ) {
            lua_pop( L, 1 );
            lua_pushlstring( L, s, len );
            /* Save it in the registry. */
            lua_pushlightuserdata( L, s );
            lua_pushvalue( L, -2 );
            lua_rawset( L, LUA_REGISTRYINDEX );

Given that, you can then avoid repeated hashing of the string when pushing

I use this last idiom enough for a variety of types of objects that I wish
there were support for lua_rawgetud and lua_rawsetud similar to lua_rawgeti
and lua_rawseti which would index based on a light userdata. (I'm using the
raw form to match the integer indexed versions. I don't actually have a
strong reason to prefer it to the full form.)