[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Benchmarking a custom _while loop in Lua vs. LuaJIT (and question about tail calls)
- From: Pierre-Yves Gérardy <pygy79@...>
- Date: Thu, 18 Feb 2010 12:06:47 +0100
I've been testing various implementations of the custom _while loop
described in the thread about "continue".
The code I tested, for all versions, equivalent to
local a=1
while a < 10000000 do a = a + 1 end
After benchmarking, it turns out that
* LuaJIT offers a 20 x boost for the standard while loop, and a 130 x
boost for my _while() variant.
* _while() is almost as fast as a vanilla while loop in LuaJIT, but
7.8 times slower in Lua 5.1
* the overhead of a tail call relative to a while loop (test 3 and 2
respectively) is only halved in LuaJIT, which is far from the gains it
provides usually.
The first two points are just amazing, but the third one is
puzzling... Is there somthing inherently slow in the elimination of
tail calls? Or hasn't it been optimized [ yet | on purpose ]?
The code follows the benchmark results.
11-84-169-81:~ Pygy$ time lua while.lua
real 0m0.559s
user 0m0.532s
sys 0m0.004s
11-84-169-81:~ Pygy$ time lua _while.lua
real 0m4.215s
user 0m4.179s => ~7.5 times slower
sys 0m0.008s
11-84-169-81:~ Pygy$ time lua _while_recursive.lua
real 0m6.012s
user 0m5.979s => an overhead of 1.8 seconds relative to the former
sys 0m0.010s
11-84-169-81:~ Pygy$ time luajit while.lua
real 0m0.033s
user 0m0.027s => Wow!
sys 0m0.003s
11-84-169-81:~ Pygy$ time luajit _while.lua
real 0m0.036s
user 0m0.031s => Woah!!
sys 0m0.003s
11-84-169-81:~ Pygy$ time luajit _while_recursive.lua
real 0m0.977s
user 0m0.959s => an overhead of ~900 ms... ???
sys 0m0.004s
-- while.lua --
local a=1
while a < 10000000 do a = a + 1 end
----------------
-- _while.lua --
do
local mtw ={
__concat=function(c,f)
local cond=c[1]
while(cond() and not f(1)) do end
end
}
_while = function(c) return setmetatable({c},mtw) end
end
local a=1
w = _while(function()return a < 10000000 end) .. function()
a = a + 1
end
----------------
-- _while_recursive.lua --
local _while
_while = function(c,f)
if c() and not f() then
return _while(c,f)
end
end
local a=1
_while (function()return a < 10000000 end, function()
a = a + 1
end)
-- _while_recursive2.lua --
-- it has the same profile as the above so I didn't post the
-- benchmark results. (it's only a teeny tiny bit slower),
-- so I guess that accessing an upvalue is not the problem.
do
local _while_r
_while_r = function(c,f,w) if c() and not f() then return w(c,f,w) end end
_while = function(c,f) return _while_r(c,f,_while_r) end
end