Hi,
Currently, as I understand it, the metatable of a Lua value
is a Lua table with string keys "__index", "__add",
"__tostring", etc. These string keys are stored in a hash
table and incur a hash-table lookup whenever accessing a
metatable, i.e., if I write something like
t = {}
setmetatable(t,
{__index = {a = function() return "b" end}})
then upon calling t:a(),
Lua will perform three hash-table lookups: one check
for 'a' in 't', one check for __index in t's
metatable, and finally a check for 'a' in the method table.
But accessing __index
by a string lookup in a hash table seems unnecessarily
complicated, when for metatables we are always interested in
the same 20 or so keys. Instead, Lua could simply define
global values:
__index = 1
__newindex = 2
__tostring = 3
-- and so on
and then we write the metatables like this:
t = {}
setmetatable(t,
{[__index] = {a = function() return "b" end}})
Now we have exchanged a hash-table lookup for an array
lookup. The code is not really more complicated; you have to
type only two more characters. Plus, many people will use an
OOP library that abstracts away the whole metatable creation,
so they wouldn't notice any difference. Practically everything
using metatables immediately gets faster. Other than backwards
compatibility, I'm having trouble thinking of a downside.
In fact, if I understand correctly, Lua already stores a
list of metatable keys, looks up the key by an index, and then
does a hash lookup for that key in the metatable:
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
/* define mt (omitted for brevity) */
return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject);
}
Obviously the last line should be faster if it were just:
return (mt ? luaH_getint(mt, event) : luaO_nilobject);
...right?
Best,
Mason