lua-users home
lua-l archive

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

On Sat, Nov 26, 2011 at 9:03 AM, Roberto Ierusalimschy
<> wrote:
> The main motivation is to allow what Rapin just suggested in a message
> to this thread.
On Sat, Nov 26, 2011 at 1:13 PM, Peter Cawley <> wrote:
> function table.pack(...) local t = {__len = select('#', ...), ...} return setmetatable(t, t) end

One of the awkward vararg handling tests [1] was to append a value to
an argument list.  In 5.2.0rc2, we can write

  function append(x, ...)
    local t = table.pack(...)
    t.n = t.n + 1; t[t.n] = x  -- i.e. analogous to table.insert(t, x)
    return table.unpack(t, 1, t.n)

Even if table.pack did set __len, then table.insert would still be of
questionable use here if (as it does in 5.2.0rc2) it reads from but
did not write back to the value in __len.

IMHO, the main benefit of table.insert/table.remove (other than
convenience) is for the efficient underlying "memmove"-like block move
both of these do.  Observe that the pure Lua implementation of
table.insert is about 3.5 times as slow:

  local function tinsert(list, pos, value)
    for i=#list,pos,-1 do list[i+1] = list[i] end
    list[pos] = value
  -- local tinsert = table.insert
  local t = {}; for i=1,1e4 do tinsert(t, 1, i) end; print(#t)

(Curiously, the pure Lua implementation is twice as fast on LuaJIT,
though apparently only because the table.insert optimization is not
yet implemented -- "NYI: unsupported variant of FastFunc

Lua does not, however, expose the underlying memmove.  Perhaps it
would be useful.  During profiling of LuaInspect, I observed one of
the bottlenecks was in inserting a bunch of tokens into another token
list via repeated table.insert's (quadratic), so I basically had to
implement that missing table function in pure Lua:

  local function tinsertlist(t, i, bt)
    local oldtlen, delta = #t, i - 1
    for ti = #t + 1, #t + #bt do t[ti] = false end -- preallocate (avoid holes)
    for ti = oldtlen, i, -1 do t[ti + #bt] = t[ti] end -- shift
    for bi = 1, #bt do t[bi + delta] = bt[bi] end -- fill