Last active
May 4, 2026 19:15
-
-
Save EngineerSmith/f99c1ba503ec090f34b0659978a829c7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --[[ | |
| ------- | |
| 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