lua-users home
lua-l archive

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


Hi all,

I am trying to define a custom data structure which represents a vector of real
numbers (non resizable). 
I am using FFI for storage because (among other considerations) I need
compatiblity with external C++ code which operates on dense vectors.
   
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.
Running luajit -jv gives "NYI: return to lower frame" warnings but I cannot
interpret these.

I am aware such code is not indicative of typical use, but because this data
structure (toghether with the dense matrix one) is a fundamental quantity in my
library I would like to make sure that I am not doing silly mistakes here :P

I have already used lua (and luajit 2.0) in a small project and I am definetely
very impressed with it.

Thank you in advance for your help!
Please be gentle, I am a newbie :)


Best regards,
KR

------------------------------------------------------------
local ffi = require("ffi")

local n = 30000000
local incr = 0.000156
local y = 0.0
local start, stop

local Alg = {}
function Alg:val(i)
  return self.v[i]
end
function Alg:setVal(i, value)
  self.v[i] = value
end
Alg.mt_vec = {__index = Alg.val, __newindex = Alg.setVal}

function Alg.newvec(n) 
  local ret = {}
  ret.v = ffi.new("double[?]", n)

  ret.val = Alg.val
  ret.setVal = Alg.setVal

  setmetatable(ret, Alg.mt_vec)
  return ret
end

function bench(x) 
  --write
  for i=0, n-1 do
    x[i] = incr
  end
  --read
  for i=0, n-1 do
    y = y + x[i]
  end
end

print("\nNewVec alloc")
start = os.clock()
local newVec = Alg.newvec(n)
stop = os.clock()
print(stop - start)

print("\nNewVec run [i] (metatable)")
start = os.clock()
bench(newVec)
stop = os.clock()
print(stop - start)

print("\nNewVec run via :setVal(i, v) and :val(i)")
start = os.clock()
for i=0, n-1 do
  newVec:setVal(i, incr) 
end
--read
for i=0, n-1 do
  y = y + newVec:val(i)
end
stop = os.clock()
print(stop - start)

print("\nNewVec run direct call to .v[i]")
start = os.clock()
for i=0, n-1 do
  newVec.v[i] = incr
end
--read
for i=0, n-1 do
  y = y + newVec.v[i]
end
stop = os.clock()
print(stop - start)

print("\nFFI vec alloc")
start = os.clock()
local vec = ffi.new("double[?]", n)
stop = os.clock()
print(stop - start)

print("\nFFI vec run")
start = os.clock()
bench(vec)
stop = os.clock()
print(stop - start)

print("\nLua table first run")
start = os.clock()
local tabl = {}
bench(tabl)
stop = os.clock()
print(stop - start)

print("\nLua table second run")
start = os.clock()
bench(tabl)
stop = os.clock()
print(stop - start)

print("\nCHECKSUM: ", y)
----------------------------------------------------------