lua-users home
lua-l archive

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

On Thu, Feb 28, 2008 at 7:43 PM, Diego Nehab <> wrote:
>  Sure. I don't have the code on me right now. The main
>  ideas is this:
>      Avoid the strings as class names. Use lightuserdata
>      instead. The key contains the addresses of the strings, not
>      the values of the strings. The strings are extern const
>      strings defined in whatever module created the class, and
>      exported in its .h file.
>  So to set a userdata to a class, you only need one rawget,
>  using a lightuserdata as key, from the class table (which
>  can be the registry or a private table in an upvalue), plus
>  one setmetatable.
>  To check a userdata you need one touserdata, that one rawget,
>  one getmetatable, and one isequal.
>  The savings come from the fact you don't traverse strings,
>  ever, and you don't create strings, ever.

I agree with the above.

I don't have the numbers anymore, but wxLua has switched to using
lightuserdata table keys as well. For example, we push lightuserdata
of the address of const char* strings as keys to our tables in the

However, we do use integer values for our userdata types and store a
table in the LUA_REGISTRYINDEX that maps the integers keys to a table
of other info about the userdata. This allows us to simply extend the
Lua types (integers) with our wxLua types so we only have to pass a
single integer between functions and not the integer Lua type plus the
void* lightuserdata corresponding to the wxLua type since we don't
want every function to have keep looking up the wxLua type.

However, the simplicity and clarity of using a string as the
userdata's type is very appealing and would follow what Lua itself
does ("FILE*" for example), but I opted for speed.

I found that the Lua functions to hash string keys took much of a
simple program's time as seen with cachegrind.

local p = wx.wxPoint(0,0)
for i = 1, 1E4
    p:SetX(5) -- forces a lookup of the wxLua userdata type of 'p'

// wxLua userdata metatable structure:
// {
//    lightuserdata(&wxlua_metatable_type_key) = wxLua type number in
wxlua_lreg_types_key table
//    lightuserdata(&wxlua_metatable_wxluabindclass_key) =
//    __gc       = function(wxlua_wxLuaBindClass__gc)
//    __index    = function(wxlua_wxLuaBindClass__index)
//    __newindex = function(wxlua_wxLuaBindClass__newindex)
//    __tostring = function(wxlua_wxLuaBindClass__tostring)
// }