[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: Most efficient way to recognize a line by its first (up to) three characters
- From: Thijs Schreijer <thijs@...>
- Date: Wed, 12 Mar 2014 11:47:24 +0000
> -----Original Message-----
> From: lua-l-bounces@lists.lua.org [mailto:lua-l-bounces@lists.lua.org] On
> Behalf Of meino.cramer@gmx.de
> Sent: dinsdag 11 maart 2014 19:25
> To: Lua mailing list
> Subject: Re: Most efficient way to recognize a line by its first (up to)
> three characters
>
> Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> [14-03-11 19:16]:
> > > local prefix, info = line:sub(1,3), line:sub(4)
> > > if prefix == "abc" then
> > > -- do something
> > > elseif prefix == "123" then
> > > -- do something else
> > > elseif ...
> >
> > Consider this scheme instead of a chain of ifs:
> >
> > local handlers={
> > ["abc"]=function (prefix,info) ... end,
> > ["123"]=function (prefix,info) ... end,
> > }
> >
> > local badprefix=function (prefix,info) error("cannot handle "..prefix) end
> >
> > while true do
> > local prefix, info = line:sub(1,3), line:sub(4)
> > local h = handlers[prefix] or badprefix
> > h(prefix,info)
> > end
> >
>
> ...whow!...
>
> But how can I handle different length of prefixes with directly
> following data... ?
>
>
>
You could test whether you can include the data in the test. Use lazy evaluation to build the function table using if-thens or whatever then put the actual 3 bytes as a key in there;
local flist = {}
local tablesize = 0
local f1 = function(line) ... do something ... end
local f2 = function(line) ... do something ... end
local function loadfunc(line)
local f
local key = line:sub(1,3)
local key1 = line:sub(1,1)
if key1 == "a" then
f = f1
elseif key1 == "b" then
local key2 = line:sub(2,2)
if key2 == "*" then
f = f2
end
end
if not f then error("unknown command sequence") end
flist[key] = f -- store in lazy list
tablesize = tablesize + 1 -- just in here to measure table size
return f(line)
end
local handledata = function(line)
return (flist[line:sub(1,3)] or loadfunc)(line)
end
This will deliver some duplication in the lookup table. A single charcter command will be in there with all variations of the data following it in the next two bytes. How much duplication it delivers depends on your data.
NOTE: if you inline the function f1 and f2, then I'm not sure they will be duplicated in memory, or whether a single function instance will be reused. Hence I wrote them as locals above, making sure every function is only created once.
Thijs