Единственное, о чем я могу думать, это исключить ненужные i
.
function expand(t)
local res = {}
for k, v in pairs(t) do
res[#res + 1] = k
res[#res + 1] = v
end
return res
end
Кроме того, я не знаю других возможных оптимизаций (в смысле компактности).
Я написал простой тест и обнаружил, что временное наказание этого кода над кодом OP увеличивается с увеличением количества ключей в таблице. По некоторым причинам он растет быстрее с luajit, чем с lua5.3.
local function benchmark(funcs, t, times)
times = times or 1000000
local s, e
local diffs = {}
for name, f in pairs(funcs) do
s = os.clock()
for i = 1, times do
f(t)
end
e = os.clock()
diffs[name] = e - s
end
return diffs
end
-- base, length and insert are functions correspond to the OP's version,
-- the version in this answer and the version with table.insert respectively.
local funcs = { base = base, length = length, insert = insert }
io.write('nkeys\tbase\tlength\tinsert\n')
for _, nkeys in ipairs{4, 8, 16, 32, 64} do
-- get_tab(n) returns a table with n keys. Its definition is omitted.
local res = benchmark(funcs, get_tab(nkeys))
io.write(string.format("%d\t1.0\t%.2f\t%.2f\n",
nkeys, res.length/res.base, res.insert/res.base))
end
output:
$ luajit ./flatten.lua
nkeys base length insert
4 1.0 1.15 1.55
8 1.0 1.33 1.89
16 1.0 1.55 2.47
32 1.0 1.72 2.82
64 1.0 2.00 3.72
$ lua5.3 ./flatten.lua
nkeys base length insert
4 1.0 1.13 1.56
8 1.0 1.24 1.78
16 1.0 1.28 1.95
32 1.0 1.36 2.12
64 1.0 1.56 2.34
Мы также можем видеть, что table.insert()
даже медленнее, чем res[#res + 1] =
.