lua-users home
lua-l archive

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


KR wrote:
> The issue I am having is that in the test code below the access
> to the elements of the vector via a metatable via __index and
> __newindex seems to be slower than the remaining ways of
> accessing this elements I have tested.

The problem in your case are the Lua semantics for __newindex:
they require checking that the table _doesn't_ contain the key
before calling the __newindex metamethod.

So it's really doing this:

  for i=0,n-1 do
    if rawget(x, i) == nil then
      Alg.setVal(x, i, incr)
    else
      rawset(x, i, incr)
    end
  end

The JIT compiler realizes the array part of the Lua table 'x' is
empty and it doesn't need to be checked. But the hash part is not
empty. Any key could be present or not -- it must be checked with
a (costly) lookup in the hash part. I.e. the rawget() cannot be
optimized away.

E.g. try adding 'ret[12345] = 1' at the end of Alg.newvec. This
index will later be overwritten with a new value and Alg.setVal
won't be called for this key. There's no way the JIT compiler can
know a priori that no such key is present in the Lua table.

Same issue with __index. These are standard Lua semantics and not
something I can change.

You could use a userdata to avoid this, since indexing userdata
calls __index or __newindex without any steps inbetween. But that
has it's own issues. As has been pointed out, the best solution is
to directly access the cdata.

[That said, I'll likely add metamethods to cdata soon. This will
give you more flexibility with indexing, too. But abstractions
_do_ have a certain cost. Not everything can be optimized away.]

> Running luajit -jv gives "NYI: return to lower frame" warnings but I cannot
> interpret these.

This is normal. It's just the region selection heuristics at work.
It figures out the correct trace to compile right after that.

--Mike