Skip to content

Instantly share code, notes, and snippets.

@SkyyySi
Last active March 18, 2025 07:27
Show Gist options
  • Save SkyyySi/dce94707e15c1f5c304285cf9c524abc to your computer and use it in GitHub Desktop.
Save SkyyySi/dce94707e15c1f5c304285cf9c524abc to your computer and use it in GitHub Desktop.
A quick performance test comparing closures and regular functions in Lua
local function benchmark(func, name, times, ...)
name = name or "<anonymous>"
times = times or 100000
io.write(name, " --> ")
io.flush()
local time_start = os.clock()
for i = 1, times do
func(...)
end
local time_finish = os.clock()
print(string.format(
"took %.03fs",
time_finish - time_start
))
end
local debug_env_before = function(env) end
local debug_env_after = function(env) end
local env_shared = {}
local func_shared = function(env)
local result = 1
for i = 1, 100 do
result = result * i
end
return result
end
do
local exe_func
exe_func = function(func, env)
return (function(_arg_0, ...)
local ok = _arg_0
if ok then
return ...
else
return --os.exit(1)
end
end)(xpcall(function()
debug_env_before(env)
func(env)
return debug_env_after(env)
end, function(ex)
error(ex)
return ex
end))
end
benchmark(exe_func, "Without stub")
end
do
local __exe_func__stub_0 = function(_arg_0, ...)
local ok = _arg_0
if ok then
return ...
else
return --os.exit(1)
end
end
local __exe_func__stub_1 = function(env)
debug_env_before(env)
func(env)
return debug_env_after(env)
end
local __exe_func__stub_2 = function(ex)
error(ex)
return ex
end
local exe_func
exe_func = function(func, env)
return __exe_func__stub_0(xpcall(__exe_func__stub_1, __exe_func__stub_2, env))
end
benchmark(exe_func, "With stub")
end
local function benchmark(name, func, ...)
name = name or "<anonymous>"
io.write(name, " --> ")
io.flush()
local time_start = os.clock()
for i = 1, 1000000 do
func(...)
end
local time_finish = os.clock()
print(string.format(
"took %.03fs",
time_finish - time_start
))
end
local function test_func(operation)
local result = 1
for i = 1, 100 do
result = operation(result, i)
end
return result
end
benchmark("Without capture", test_func, function(acc, i)
return acc * i
end)
benchmark("With capture", function()
test_func(function(acc, i)
return acc * i
end)
end)
--[===[
With Lua5.1:
Without capture --> took 2.705s
With capture --> took 2.872s
With Lua5.2:
Without capture --> took 2.718s
With capture --> took 2.725s
With Lua5.3:
Without capture --> took 2.368s
With capture --> took 2.413s
With Lua5.4:
Without capture --> took 2.292s
With capture --> took 2.314s
With LuaJIT:
Without capture --> took 0.094s
With capture --> took 0.136s
--]===]
for lua in {5.1,5.2,5.3,5.4,jit}; do
echo "With Lua${lua:u}:"
"lua${lua}" ./benchmark.lua
echo
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment