lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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