No way to get uservalue count from API; intended?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

No way to get uservalue count from API; intended?

Sergey Zakharchenko
Hello,

Is there a reason not to include the ability to read the number of
uservalues associated with a userdata
(lua_getiuservalue()/lua_setiuservalue()) into the API? That would
allow a slightly more efficient tuple implementation, among other
things...

Best regards,

--
DoubleF
Reply | Threaded
Open this post in threaded view
|

Re: No way to get uservalue count from API; intended?

Roberto Ierusalimschy
> Is there a reason not to include the ability to read the number of
> uservalues associated with a userdata
> (lua_getiuservalue()/lua_setiuservalue()) into the API?

No specific reason except the usual (to avoid bloating the API with
functions seldom used.)


> That would
> allow a slightly more efficient tuple implementation, among other
> things...

Would you mind sharing with us that implementation and the other things?

-- Roberto
Reply | Threaded
Open this post in threaded view
|

Re: No way to get uservalue count from API; intended?

Sergey Zakharchenko
Roberto,

Roberto Ierusalimschy <[hidden email]>:
> Would you mind sharing with us that implementation and the other things?

I never mind sharing something that's not mine:)
http://lua-users.org/lists/lua-l/2018-03/msg00330.html

A sizeof(unsigned short), and possibly more, could be saved if it
didn't have to store the uservalue count.

Other things would mostly be debugging-related (though performance
would then be irrelevant).

I'm inspecting efficiency of different ways of storing a possibly
variable number of arguments. Options considered:
t1: create a single table, fill in place;
u1: create a single tuple, fill in place;
tN: create a new table every time;
uN: create a new tuple every time;
t0: create a single table, assign using a[1],a[2],a[3]=...
(effectively cheating as this limits argument count)

One possibly useful thing I can share is the benchmark result set of
these options (4 elements actually assigned, 1 mln loop iterations,
median of 10, MIPS, somewhat patched Lua 5.4.0):
t1: 5.865s
u1: 7.315s
tN: 26.695s
uN: 14.97s
t0: 2.425s

As you see, tuples beat tables if we (have to) create a new one every
time; tables beat tuples when they can be reused (assignment performed
via lua_rawseti in a loop vs lua_setiuservalue in a loop). The
"cheating" variant is there to provide a baseline to compare against.

Best regards,

--
DoubleF
Reply | Threaded
Open this post in threaded view
|

Re: No way to get uservalue count from API; intended?

Jonathan Goble
On Tue, Aug 18, 2020 at 1:37 PM Sergey Zakharchenko <[hidden email]> wrote:
t0: create a single table, assign using a[1],a[2],a[3]=...
(effectively cheating as this limits argument count)

A better version of this is `a = {...}`.
Reply | Threaded
Open this post in threaded view
|

Re: No way to get uservalue count from API; intended?

Sergey Zakharchenko
In reply to this post by Roberto Ierusalimschy
Roberto,

Roberto Ierusalimschy <[hidden email]>:
>
> > Is there a reason not to include the ability to read the number of
> > uservalues associated with a userdata
> > (lua_getiuservalue()/lua_setiuservalue()) into the API?
>
> No specific reason except the usual (to avoid bloating the API with
> functions seldom used.)

Speaking of which, it looks like luaL_checkudata/luaL_testudata are
quite often used, but also quite inefficient (if the rest of the
method runs fast), which seems to cause the somewhat strange benchmark
results I sent earlier. It looks up a metatable by name, then it gets
the actual one, compares them and pops both. Tuple-related benchmarks
look much better if I drop the metatable check.

A more efficient lower-level API could be, say, lua_testmetatable(L,
idx_tested, idx_of_metatable) which would return e.g. 1 if the value
at the idx_tested index has the metatable supplied at idx_of_metatable
(all done via pointer comparisons, no metatable pushing/popping), 0 if
it has no metatable at all, and -1 if it has a metatable but it's
different from the supplied one. The method would have the expected
metatable as an upvalue.

Best regards,

--
DoubleF