Skip to content

Instantly share code, notes, and snippets.

@EngineerSmith
Last active May 4, 2026 19:15
Show Gist options
  • Select an option

  • Save EngineerSmith/f99c1ba503ec090f34b0659978a829c7 to your computer and use it in GitHub Desktop.

Select an option

Save EngineerSmith/f99c1ba503ec090f34b0659978a829c7 to your computer and use it in GitHub Desktop.
--[[
-------
My messy benchmarking file for debug.getinfo vs jit.util.funcinfo
I found, that funcinfo cannot beat the speed of debug.getinfo - because jit.util.funcinfo needs
a reference to the calling function which requires a debug.getinfo call itself.
I managed to get the speed down to these sats as the file stands:
test_1 (debug.info) took: -- AppleCake 2.1 solution
Avg: 0.00049ms
Worse: 0.01820ms
Best: 0.00030ms
---
test_2 (jit.util) took:
Avg: 0.00077ms
Worse: 0.01870ms
Best: 0.00050ms
---
test_3 (fast?) took:
Avg: 0.00057ms
Worse: 0.01860ms
Best: 0.00030ms
---
test_4 (final solution) took:
Avg: 0.00045ms
Worse: 0.01280ms
Best: 0.00030ms
-- Note, if you add :gsub(":", "@") into fast_name, it bumps `best` to 0.00040ms, not worth it for styling
-------
]]--
local jit_util = require("jit.util")
local old_name = function()
local info = debug.getinfo(2, "fnS")
local name
if info.name then
name = info.name
elseif info.func then -- Attempt to create a name from memory address
name = tostring(info.func):sub(10)
else
error("Could not generate name for this function")
end
if info.short_src then
name = name.."@"..info.short_src..(info.linedefined and "#"..info.linedefined or "")
end
return name
end
local new_name = function()
local info = debug.getinfo(2, "fn")
if info then
local name
if info.name then
name = info.name
elseif info.func then
name = tostring(info.func):sub(10)
else
error("Could not generate name for this function")
end
if info.func then
local j_info = jit_util.funcinfo(info.func)
if j_info and j_info.source then
local short_src = j_info.source
local prefix = short_src:sub(1, 1)
if prefix == "@" or prefix == "=" then
short_src = short_src:sub(2)
else
short_src = '[string "' .. short_src:sub(1, 40) .. '..."]'
end
name = name .. "@" .. short_src .. (j_info.linedefined and "#" .. j_info.linedefined or "")
end
end
return name
end
end
local fast_name = function() -- The two C calls is the issue,
local info = debug.getinfo(2, "f")
if not info then return "unknown" end
local j_info = jit_util.funcinfo(info.func)
-- local name = info.name or tostring(info.func):sub(10)
local name
if j_info and j_info.source then
-- local src = j_info.source
-- local prefix = src:sub(1, 1)
-- if prefix == "@" or prefix == "=" then
-- src = src:sub(2)
-- end
-- name = name .. "@" .. src .. (j_info.linedefined and "#" .. j_info.linedefined or "")
-- name = name .. "@" .. src .. "#" .. j_info.linedefined
name = j_info.loc--:gsub(":", "@")
-- print(name)
-- name = ("%s@%s"):format(name, src)
end
return name
end
local generateFuncName = function()
local info = debug.getinfo(3, "fnS")
local name = info.name or tostring(info.func):sub(10)
if info.short_src then
name = name .. "@" .. info.short_src
end
if info.linedefined then
name = name .. "#" .. info.linedefined
end
return name
end
local _getTime = love.timer.getTime
local getTime = function() -- Time in microseconds
return _getTime() * 1e+6
end
local benchmark = function(name, func, iterations)
local total = 0
local best = math.huge
local worse = 0
-- warmup
for _ = 1, 100 do func() end
for _ = 1, iterations do
local s = getTime()
func()
local f = getTime()
local d = f - s
total = total + d
if d < best then best = d end
if d > worse then worse = d end
end
local avg = total / iterations
print(("%s took:\n Avg: %.5fms\n Worse: %.5fms\n Best: %.5fms"):format(
name, avg / 1000, worse / 1000, best / 1000
))
end
local n = 100000
local test_1 = function() return old_name() end
local test_2 = function() return new_name() end
local test_3 = function() return fast_name() end
local test_4 = function() return generateFuncName() end
benchmark("test_1 (debug.info)", test_1, n)
print("---")
benchmark("test_2 (jit.util)", test_2, n)
print("---")
benchmark("test_3 (fast?)", test_3, n)
print("---")
benchmark("test_4 (final solution)", test_4, n)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment