From 0e48ac1dfe9896bc62bcfb02218adc4d97e8a6c6 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 4 May 2023 19:46:40 +0100 Subject: [PATCH] Speed up JSON string parsing We now use Lua patterns to find runs of characters. This makes string parsing 3-4x faster. Ish - I've not run any exact benchmarks. Closes #1408 --- .../data/computercraft/lua/rom/apis/textutils.lua | 14 +++++++++++--- projects/fabric/src/main/resources/fabric.mod.json | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua index 87b731186..353dbb799 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua @@ -533,12 +533,18 @@ do local function parse_string(str, pos, terminate) local buf, n = {}, 1 + -- We attempt to match all non-special characters at once using Lua patterns, as this + -- provides a significant speed boost. This is all characters >= " " except \ and the + -- terminator (' or "). + local char_pat = "^[ !#-[%]^-\255]+" + if terminate == "'" then char_pat = "^[ -&(-[%]^-\255]+" end + while true do local c = sub(str, pos, pos) if c == "" then error_at(pos, "Unexpected end of input, expected '\"'.") end if c == terminate then break end - if c == '\\' then + if c == "\\" then -- Handle the various escapes c = sub(str, pos + 1, pos + 1) if c == "" then error_at(pos, "Unexpected end of input, expected escape sequence.") end @@ -552,8 +558,10 @@ do if not unesc then error_at(pos + 1, "Unknown escape character %q.", c) end buf[n], n, pos = unesc, n + 1, pos + 2 end - elseif c >= '\x20' then - buf[n], n, pos = c, n + 1, pos + 1 + elseif c >= " " then + local _, finish = find(str, char_pat, pos) + buf[n], n = sub(str, pos, finish), n + 1 + pos = finish + 1 else error_at(pos + 1, "Unescaped whitespace %q.", c) end diff --git a/projects/fabric/src/main/resources/fabric.mod.json b/projects/fabric/src/main/resources/fabric.mod.json index 0e638d0c4..189e29bcd 100644 --- a/projects/fabric/src/main/resources/fabric.mod.json +++ b/projects/fabric/src/main/resources/fabric.mod.json @@ -47,7 +47,7 @@ ], "depends": { "fabricloader": ">=0.14.17", - "fabric-api": ">=0.78.0", + "fabric-api": ">=0.80.0", "minecraft": ">=1.19.4 <1.20" }, "accessWidener": "computercraft.accesswidener"