lua-users home
lua-l archive

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



On 17/09/14 01:28 PM, Steven Degutis wrote:
Fwiw, I've made a gist out of this code so I can read it better:

https://gist.github.com/anonymous/b66c3d75efb20cdc2e2f

Quoth Thiago L.:
[ tons of unformatted code ]
Uhh... huh...

Seems like my email client broke the formatting :/

Let's try again:

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, and 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?