Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easy Lua profiling

I just started with Lua as part of a school assignment. I'd like to know if there's an easy way to implement profiling for Lua? I need something that displays allocated memory, variables in use regardless of their type, etc.

I've been finding C++ solutions which I have been able to compile successfully but I don't know how to import them to the Lua environment.

I also found Shinny but I couldn't find any documentation about how to make it work.

like image 988
Raúl Roa Avatar asked Mar 31 '13 02:03

Raúl Roa


1 Answers

There are several profilers available that you can check, but most of them target execution time (and are based on debug hook).

To track variables, you will need to use debug.getlocal and debug.getupvalue (from your code or from debug hook).

To track memory usage you can use collectgarbage(count) (probably after collectgarbage(collect)), but this only tells you total memory in use. To track individual data structures, you may need traverse global and local variables and calculate the amount of space they take. You can check this discussion for some pointers and implementation details.

Something like this would be the simplest profiler that tracks function calls/returns (note that you should not trust absolute numbers it generates, only relative ones):

local calls, total, this = {}, {}, {}
debug.sethook(function(event)
  local i = debug.getinfo(2, "Sln")
  if i.what ~= 'Lua' then return end
  local func = i.name or (i.source..':'..i.linedefined)
  if event == 'call' then
    this[func] = os.clock()
  else
    local time = os.clock() - this[func]
    total[func] = (total[func] or 0) + time
    calls[func] = (calls[func] or 0) + 1
  end
end, "cr")

-- the code to debug starts here
local function DoSomethingMore(x)
  x = x / 2
end

local function DoSomething(x)
  x = x + 1
  if x % 2 then DoSomethingMore(x) end
end

for outer=1,100 do
  for inner=1,1000 do
    DoSomething(inner)
  end
end

-- the code to debug ends here; reset the hook
debug.sethook()

-- print the results
for f,time in pairs(total) do
  print(("Function %s took %.3f seconds after %d calls"):format(f, time, calls[f]))
end
like image 143
Paul Kulchenko Avatar answered Jan 01 '23 19:01

Paul Kulchenko