[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: optimisation question
- From: RLake@...
- Date: Thu, 3 Jul 2003 10:49:16 -0500
> I have a function I would like to optimize (yes, I've done profiling).
> it transforms string like "3-7" into "3,4,5,6,7".
Try this:
function transform(str)
local _, _, from, to = string.find(str, "^(%d+)%-(%d+)$")
assert(from, "Transform needs a string in the format i-j")
local n1, n2 = tonumber(from), tonumber(to)
if n1 >= n2 then return from end
local template = from .. string.rep(", ", n2 - n1)
return (string.gsub(template, " ", function() n1 = n1 + 1; return n1
end))
end
Philippe had a good idea about memoising results; the above can be
improved
(slightly) by memoising the template string. (It only helps on largish
ranges.)
-- A useful tool:
function memoise(fn)
return setmetatable({}, {
__index = function(t, k)
local rv = fn(k)
t[k] = rv
return rv
end
})
end
do
local function make_template(k)
return " " .. string.rep(", ", k)
end
local template = memoise(make_template)
function transform2(str)
local _, _, from, to = string.find(str, "^(%d+)%-(%d+)$")
assert(from, "Transform needs a string in the format i-j")
local n1, n2 = tonumber(from), tonumber(to)
if n1 >= n2 then return from end
return (string.gsub(template[n2 - n1], " ",
function() local rv = n1; n1 = n1 + 1; return rv end))
end
end
The test for n1 >= n2 is actually unnecessary, but that counts on a
particular behaviour of string.rep. In fact, the conversion of from
and to to numbers is also unnecessary (if the comparison is removed),
because it will happen automatically. So making those changes, we
could reduce the code to the following: (shorter, if not faster)
do
local function make_template(k)
return " " .. string.rep(", ", k)
end
local template = memoise(make_template)
function transform3(str)
local _, _, from, to = string.find(str, "^(%d+)%-(%d+)$")
assert(from, "Transform needs a string in the format i-j")
return (string.gsub(template[to - from], " ",
function() local rv = from; from = from + 1; return rv end))
end
end