lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> -----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