Blockhead,
I came up with this set of changes that seems to slightly improve
performance, at least with the set of data I used for the test (a 3.6MB
advtrains_interlocking.ls file from a set of savefiles sent to me by a
server admin). Part of this is taken from a patch that I filed to
advtrains-devel a while ago.
For Festus' test, however, I do not think this will bring much
improvement (if at all).
---
serialize_lib/serialize.lua | 65 +++++++++++++++++++++++++------------
1 file changed, 44 insertions(+), 21 deletions(-)
diff --git a/serialize_lib/serialize.lua b/serialize_lib/serialize.lua
index 78ddcfd..be7e29f 100644
--- a/serialize_lib/serialize.lua+++ b/serialize_lib/serialize.lua
@@ -40,13 +40,30 @@ In strings the following characters are escaped by &
All other characters are unchanged as they bear no special meaning.
]]
+local escape_table = {+ ["&"] = "&",+ [":"] = ":",+ ["\r"] = "r",+ ["\n"] = "n",+}+local unescape_table = {}+local escape_match, unescape_match = {}, {}+for k, v in pairs(escape_table) do+ unescape_table["&"..v] = k+ escape_table[k] = "&"..v+ table.insert(escape_match, k)+ table.insert(unescape_match, v)+end+escape_match = "[" .. table.concat(escape_match) .. "]"+unescape_match = "&[" .. table.concat(unescape_match) .. "]"++escape_lookup = {}+unescape_lookup = {}+local write_table, literal_to_string, escape_chars, table_is_empty
function table_is_empty(t)
- for _,_ in pairs(t) do- return false- end- return true+ return next(t) == nilend
function write_table(t, file, config)
@@ -77,32 +94,35 @@ function write_table(t, file, config)
end
function value_to_string(t)
- if type(t)=="table" then+ local tp = type(t)+ if tp=="table" then file:close()
error("Can not serialize a table in the key position!")
- elseif type(t)=="boolean" then+ elseif tp=="boolean" then if t then
return "B1"
else
return "B0"
end
- elseif type(t)=="number" then+ elseif tp=="number" then return "N"..t
- elseif type(t)=="string" then+ elseif tp=="string" then return "S"..escape_chars(t)
else
--error("Can not serialize '"..type(t).."' type!")
- return "S<function>"+ return string.format("S<%s>", tp) end
return str
end
function escape_chars(str)
- local rstr = string.gsub(str, "&", "&&")- rstr = string.gsub(rstr, ":", "&:")- rstr = string.gsub(rstr, "\r", "&r")- rstr = string.gsub(rstr, "\n", "&n")- return rstr+ local s = escape_lookup[str]+ if s then+ return s+ end+ s = string.gsub(str, escape_match, escape_table)+ escape_lookup[str] = s+ return send
------
@@ -145,7 +165,8 @@ function string_to_value(str, table_allow)
local rest = string.sub(str, 2)
if first=="T" then
if table_allow then
- return {}, true+ -- pre-allocate some hash entries to reduce rehashing for small tables+ return {x = nil, y = nil, z = nil}, true else
file:close()
error("Table not allowed in key component!")
@@ -175,12 +196,14 @@ function string_to_value(str, table_allow)
end
end
-function unescape_chars(str) --TODO- local rstr = string.gsub(str, "&:", ":")- rstr = string.gsub(rstr, "&n", "\n")- rstr = string.gsub(rstr, "&r", "\r")- rstr = string.gsub(rstr, "&&", "&")- return rstr+function unescape_chars(str)+ local s = unescape_lookup[str]+ if s then+ return s+ end+ s = string.gsub(str, unescape_match, unescape_table)+ unescape_lookup[str] = s+ return send
------
--
2.35.1