lua-users home
lua-l archive

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


On Sat, Mar 12, 2011 at 20:27, Daurnimator <quae@daurnimator.com> wrote:
> On 13 March 2011 13:54, HyperHacker <hyperhacker@gmail.com> wrote:
>> I was just thinking, when you write metamethods for an object that
>> also has __index and __newindex, you might want to use rawset and
>> rawget fairly often to avoid the overhead of invoking those
>> metamethods (since you probably don't need/want them for internal
>> methods such as these). However, each property you want to read/write
>> using rawset and rawget is another function call, which also has some
>> overhead.
>>
>> You could avoid this by modifying rawset and rawget to accept multiple
>> parameters and return multiple values, i.e.:
>> local a, b, c = rawget(self, 'a', 'b', 'c')
>> rawset(self, 1, a, 2, b, 3, c) --or:
>> rawset(self, {a, b, c})
>>
>> (As an example, I wrote a Vector3 class which provides __index and
>> __newindex to access the elements as v.x, v.y, v.z and v.r, v.g, v.b
>> for convenience, but actually stores them as v[1], v[2], v[3]. For
>> __add, __sub etc it's probably a lot more efficient not to go through
>> __index 6 times (3 per vector). Though, while writing I realized
>> __index isn't invoked for existing keys anyway, but that was where the
>> idea came from... Still, any code doing multiple rawget/rawset calls
>> on the same object could benefit from this.)
>>
>> --
>> Sent from my toaster.
>>
>>
>
> A different modification to rawset I've always wanted is to have it
> return the value.
> Its far too common in my code to see:
> __index = function(t,k)
>    local v = foo(k)
>    rawset(t,k,v)
>    return v
> end
>
> This could all be swapped out for tailcall:
> return rawset(t,k,foo(k))
>
> A problem with your proposal would be that raw* which is generally a
> very simple (and fast) base level function; now has to iterate over
> it's arguments.
>
>

I haven't looked at how rawset/rawget work, but if they're anything
like I imagine, you'd pretty much just put the whole body in a loop,
grabbing the next argument until it is none/nil (and the one after,
incrementing by two, for rawset), pushing one value each iteration.
Since they already check number of arguments (rawset(t, 'a') errors
while rawset(t, 'a', nil) succeeds), they could safely start the loop
counter assuming there's at least one argument. If there's no more
than one, the loop doesn't add any overhead.

I agree that having rawset return its values could also be convenient.

-- 
Sent from my toaster.