|
It was thus said that the Great JeanHeyd Meneide once stated:
> Dear Mr. Conner,
>
> If I'm understanding how lua_get/setuservalue works, I need the
> userdata to make it work. Per your example, I would do it so the __index of
> the userdata's metatable is a function. Then I have access to the userdata
> and can use `lua_getuservalue` on the userdata to get the lookup table.
> This is more or less how I was doing it before (except instead of using a
> lua table with lua_getuservalue, I was looking up into a
> std::map/boost::map of functions/variables I had stored with the userdata).
Okay, I've done similar where manually looked up the value based upon the
key [1].
> The performance bottleneck wasn't the lookup (I had reduced the
> performance impact to nothing by switching from a C++ unordered_map to a
> map since there were a very small number of elements and then using
> "transparent lookup" introduced in the new C++ standard for `map` to not
> have to create a temporary string). The performance bottleneck for the
> member function implementation was having to return the retrieved function
> to lua so it could then call it again when doing `myfoo:blah()`. (If that
> makes sense).
Not at all. Breaking down the call. Lua notices that myfoo is a
userdata. Since you are referencing a field, it looks to the metatable of
said userdata for the __index field. It's a function so it's called with
myfoo and "blah" as parameters. You do your magic and return a function.
Lua then calls that function with myfoo as a parameter. I don't see how you
can speed that up any.
> Since I already had it working before, my goal here isn't whether or
> not I can do it (I know a way to do it, like the way you said, which makes
> me somewhat happy that I'm on the right track here!), but I'm trying to get
> the utmost performance possible, so that this code has no overhead compared
> to regular C code.
^^^^^^^^^^^^^^
I'm puzzled by this phrase. You are coding in C++, not C (first off), and
second, you're using Lua---there's going to be overhead. Secondly, the
__index function doesn't know how you are going to use the resulting
value---I mean, what's the difference between:
x = myfoo.blah
and
myfoo:blah()
Both will result in this (internally in the Lua VM):
t1 = getmetatable(myfoo)
if not t1 then error() end
t2 = t1.__index
if not t2 then error() end
if type(t2) == 'function' then
t3 = t2(myfoo,"blah")
elseif type(t2) == 'table' then
t3 = t2.blah
else
error()
end
The only difference past this point is
x = t3
or
t3(myfoo)
> As a side question, is it possible to set fields to a userdata
> directly?
Could you please specify a sample of what you mean by this? I just want
to make sure I understand what you are asking.
-spc
[1] https://github.com/spc476/lua-conmanorg/blob/faf0780d01700a45e2af5d52f2c732fa45092c1e/src/process.c#L715