From b0810c51c3f075cc8a309bfb3c1714ac42b0f020 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 11 Apr 2019 11:29:16 -0300 Subject: Small optimizations in 'string.gsub' Avoid creating extra strings when possible: - avoid creating new resulting string when subject was not modified (instead, return the subject itself); - avoid creating strings representing the captured substrings when handling replacements like '%1' (instead, add the substring directly to the buffer). --- testes/gc.lua | 2 +- testes/pm.lua | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'testes') diff --git a/testes/gc.lua b/testes/gc.lua index 91e78a48..6d24e0d8 100644 --- a/testes/gc.lua +++ b/testes/gc.lua @@ -113,7 +113,7 @@ do contCreate = 0 while contCreate <= limit do a = contCreate .. "b"; - a = string.gsub(a, '(%d%d*)', string.upper) + a = string.gsub(a, '(%d%d*)', "%1 %1") a = "a" contCreate = contCreate+1 end diff --git a/testes/pm.lua b/testes/pm.lua index 8cc8772e..4d87fad2 100644 --- a/testes/pm.lua +++ b/testes/pm.lua @@ -387,5 +387,35 @@ assert(string.match("abc\0\0\0", "%\0%\0?") == "\0\0") assert(string.find("abc\0\0","\0.") == 4) assert(string.find("abcx\0\0abc\0abc","x\0\0abc\0a.") == 4) + +do -- test reuse of original string in gsub + local s = string.rep("a", 100) + local r = string.gsub(s, "b", "c") -- no match + assert(string.format("%p", s) == string.format("%p", r)) + + r = string.gsub(s, ".", {x = "y"}) -- no substitutions + assert(string.format("%p", s) == string.format("%p", r)) + + local count = 0 + r = string.gsub(s, ".", function (x) + assert(x == "a") + count = count + 1 + return nil -- no substitution + end) + r = string.gsub(r, ".", {b = 'x'}) -- "a" is not a key; no subst. + assert(count == 100) + assert(string.format("%p", s) == string.format("%p", r)) + + count = 0 + r = string.gsub(s, ".", function (x) + assert(x == "a") + count = count + 1 + return x -- substitution... + end) + assert(count == 100) + -- no reuse in this case + assert(r == s and string.format("%p", s) ~= string.format("%p", r)) +end + print('OK') -- cgit v1.2.3-55-g6feb