Apply ivan's optimisation

Thanks to Ivan (2DEngine.com), who wrote this and convinced me it was
a good idea.

This change in writing tables results in up to 20% faster
serialization in common cases, and doesn't significantly affect
performance in contrived cases.
This commit is contained in:
Robin Wellner 2015-05-25 14:15:58 +02:00
parent 48dbd6fdf3
commit 0c42f20f63
2 changed files with 10 additions and 13 deletions

19
ser.lua
View File

@ -57,18 +57,17 @@ local function write_table_ex(t, memo, rev_memo, srefs, name)
if type(t) == 'function' then if type(t) == 'function' then
return '_[' .. name .. ']=loadstring' .. make_safe(dump(t)) return '_[' .. name .. ']=loadstring' .. make_safe(dump(t))
end end
local m = {'_[', name, ']={'} local m = {}
local mi = 3 local mi = 1
for i = 1, #t do -- don't use ipairs here, we need the gaps for i = 1, #t do -- don't use ipairs here, we need the gaps
local v = t[i] local v = t[i]
if v == t or is_cyclic(memo, v, t) then if v == t or is_cyclic(memo, v, t) then
srefs[#srefs + 1] = {name, i, v} srefs[#srefs + 1] = {name, i, v}
m[mi + 1] = 'nil,' m[mi] = 'nil'
mi = mi + 1 mi = mi + 1
else else
m[mi + 1] = write(v, memo, rev_memo) m[mi] = write(v, memo, rev_memo)
m[mi + 2] = ',' mi = mi + 1
mi = mi + 2
end end
end end
for k,v in pairs(t) do for k,v in pairs(t) do
@ -76,14 +75,12 @@ local function write_table_ex(t, memo, rev_memo, srefs, name)
if v == t or k == t or is_cyclic(memo, v, t) or is_cyclic(memo, k, t) then if v == t or k == t or is_cyclic(memo, v, t) or is_cyclic(memo, k, t) then
srefs[#srefs + 1] = {name, k, v} srefs[#srefs + 1] = {name, k, v}
else else
m[mi + 1] = write_key_value_pair(k, v, memo, rev_memo) m[mi] = write_key_value_pair(k, v, memo, rev_memo)
m[mi + 2] = ',' mi = mi + 1
mi = mi + 2
end end
end end
end end
m[mi > 3 and mi or mi + 1] = '}' return '_[' .. name .. ']={' .. concat(m, ',') .. '}'
return concat(m)
end end
return function(t) return function(t)

View File

@ -47,7 +47,7 @@ _[0]={}
_[0].self=_[0] _[0].self=_[0]
return _[0]]=], 'simple cycle') return _[0]]=], 'simple cycle')
case_error({coroutine.create(function()end)}, './ser.lua:27: Trying to serialize unsupported type thread', 'unsupported type') case_error({coroutine.create(function()end)}, './ser.lua:29: Trying to serialize unsupported type thread', 'unsupported type')
case({"a", foo = "bar", ["3f"] = true, _1 = false, ["00"] = 9}, 'return {"a",["3f"]=true,_1=false,["00"]=9,foo="bar"}', 'various') case({"a", foo = "bar", ["3f"] = true, _1 = false, ["00"] = 9}, 'return {"a",["3f"]=true,_1=false,["00"]=9,foo="bar"}', 'various')
@ -58,7 +58,7 @@ case({['\127\230\255\254\128\12\0128\n\31'] = '\0'}, 'return {["\\127\\230\\255\
local x = {} local x = {}
case({x, {x}, x}, [=[ case({x, {x}, x}, [=[
local _={} local _={}
_[2]={} _[2]={nil}
_[1]={} _[1]={}
_[0]={_[1],_[2],_[1]} _[0]={_[1],_[2],_[1]}
_[2][1]=_[1] _[2][1]=_[1]