[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Index with multiple parameters?
- From: Luis Carvalho <carvalho@...>
- Date: Wed, 20 Feb 2008 04:57:47 -0500
> This is exactly the problem I'm trying to avoid. The problem is when
> you call this millions of times you get millions of temporary objects.
> It's slow (lots of memory allocation) and causes garbage collector
> thrashing.
>
> Technically with that same approach it can look "proper":
>
> vertex_vector[20].x = 2.5
>
> It's the same problem though with needing temporary objects.
Along these lines, have you tried caching temporary objects? You could use
something like this quick prototype:
-- vector.lua
local getmetatable, assert = getmetatable, assert
local newproxy, ipairs = newproxy, ipairs
local getfenv, setfenv = debug.getfenv, debug.setfenv
module(...)
local ud = {} -- cache userdata
local function register (d)
local r = ud[d]
if r == nil then
r = newproxy(true)
-- fill metatable
local m = getmetatable(r)
m.__index = function(u, k)
local e = getfenv(u)
local l = e._level
local t = d[l]
assert(t[k] ~= nil, "invalid key")
local v = e[k]
if v == nil and l < #d then
v = new(d, l + 1)
e[k] = v
end
return v
end
m.__newindex = function(u, k, v)
local e = getfenv(u)
local l = e._level
assert(l == #d, "invalid level for assignment")
e[k] = v
end
-- cache
ud[d] = r
end
return r
end
function new (d, l) -- d is dimension table, l is level
local l = l or 1
local t = {_level = l}
local u = newproxy(register(d))
return setfenv(u, t)
end
-- utils
function range (f, t) -- from, to
local r = {}
for i = f, t do r[i] = true end
return r
end
function labels (t)
local l = {}
for _, v in ipairs(t) do l[v] = true end
return l
end
[ Test ]
$ lua -lvector
Lua 5.1.2 Copyright (C) 1994-2007 Lua.org, PUC-Rio
> u = vector.new{vector.range(1, 20), vector.labels{"x", "y", "z"}}
> print(u[20].x); u[20].x = 2.5
nil
> u[1].y = 1; print(u[20].x + u[1].y)
3.5
Of course, you have to provide your userdata to "new" at the first level and
use customized getters/setters in __index and __newindex. If GC is still an
issue, you could follow Diego's suggestion in the "high performance math"
thread earlier and use lightuserdata.
Cheers,
Luis.
--
A mathematician is a device for turning coffee into theorems.
-- P. Erdos
--
Luis Carvalho
Applied Math PhD Student
Brown University