lua-users home
lua-l archive

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


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