lua-users home
lua-l archive

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


On 11/01/2011, at 12:32 PM, Mike Pall wrote:

> (*) In particular since Lua has a performance problem with empty
> or sparsely populated proxy tables: each write attempt tries to
> lookup the key and create a hash slot for it in the proxy table
> (this happens *before* even looking for __newindex). But those
> hash slots never get a value, so the keys constantly kick each
> other out. Depending on the usage pattern, this may lead to lots
> of costly branch prediction misses.

It took a while to work out how to stop LuaJIT optimising out the loops altogether - it might still be optimising more than I want.  I'm sure this is not a good test, but for what it's worth:

$ lua proxytest.lua 
   variable indexing   userdata       5063 k iterations/second
   variable indexing      table       3579 k iterations/second
   constant indexing   userdata       5231 k iterations/second
   constant indexing      table       4094 k iterations/second
$ luajit-2.0.0-beta5 proxytest.lua 
   variable indexing   userdata     393305 k iterations/second
   variable indexing      table      75364 k iterations/second
   constant indexing   userdata     396092 k iterations/second
   constant indexing      table     394164 k iterations/second


local sum = 0

function variable(p, c)
  for i = 1, c do
    p[i+1] = p[i]
  end
end

function constant(p, c)
  for i = 1, c do
    p[2] = p[1]
  end
end

function test(p, f, name)
  local start = os.clock()
  local outer, inner = 0, 100000
  while os.clock() - start < 5 do
    f(p, inner)
    outer = outer + 1
  end
  io.write(("%20s %10s %10.0f %s\n"):format(name, type(p), (outer * inner) / (os.clock() - start) / 1000, "k iterations/second"))
end

proxy = newproxy(true)
getmetatable(proxy).__index = function(t, i) return i end
getmetatable(proxy).__newindex = function(t, i, v) sum = sum + i + v end

proxytable = setmetatable({}, { __index = function(t, i) return i end, __newindex = function(t, i, v) sum = sum + i + v end })

test(proxy, variable, "variable indexing")
test(proxytable, variable, "variable indexing")

test(proxy, constant, "constant indexing")
test(proxytable, constant, "constant indexing")