lua-users home
lua-l archive

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


Hello, So I have this code for copying tables: (and table-based objects which don't rely on metatables) local function copy(inp,copies)
local todo = {[inp] = {}}
copies = type(copies) == "table" and copies or {}
copies[inp] = todo[inp]
-- we can't use pairs or for here because we modify todo
while next(todo) do
local i,o = next(todo)
todo[i] = nil
for k,v in next,i do
if copies[k] ~= nil then
k = copies[k]
elseif type(k) == "table" then
local t = {}
todo[k] = t
copies[k] = t
k = t
end
if copies[v] ~= nil then
v = copies[v]
elseif type(v) == "table" then
local t = {}
todo[v] = t
copies[v] = t
v = t
end
rawset(o,k,v)
end
end
return copies[inp] -- heh :P
end People told me to use pairs() where I have "for k,v in next,i", to respect __pairs, I told them __pairs wasn't made to make copies of things. Now the questions: Should I do it raw, but respect metatabled `copies`? Should I do it ALL raw? Or should I do it raw, respect metatabled `copies`, and look for a __copy metamethod? (Obviously, copies' metatable would override __copy. This also has the side-effect of supporting userdata copying!) Is it bad to copy tables and objects the way I'm doing it? This algorithm is optimized for tables with long chains, but not many table entries. As in, it's more (space) efficient for a.b.c.d.e.f.g = {} vs a={{},{},{},{},{}}. I also have another algorithm which is optimized for the latter. Both can be found here: https://gist.github.com/SoniEx2/fc5d3614614e4e3fe131 This algorithm would use only 1 `todo` entry for the a.b.c.d.e.f.g = {} case, and 5 for the a={{},{},{},{},{}} case. The other algorithm would use 7 call stack entries for the former case and 2 for the latter case. Is it possible to make an algorithm which's efficient for both cases? (Please note, this is all just a guess) Would LuaJIT be able to optimize this?