S0lll0s wrote:Floor all arguments:
Code: Select all
local __floor = math.floor
function math.floor(...)
tbl = {...}
for i,v in ipairs(tbl) do
tbl[i] = __floor(v)
end
return unpack(tbl)
end
Here are two alternative implementations that don't create the intermediate table "tbl":
Code: Select all
local _unpack = table.unpack
local _floor = math.floor
function floor2(...)
local tbl = {...}
for i = 1, #tbl do
tbl[i] = _floor(tbl[i])
end
return _unpack(tbl)
end
local _select = select
local _cache = {}
function floor3(...)
local n = _select('#', ...)
for i = 1, n do
_cache[i] = _floor(_select(i, ...))
end
for i = n + 1, #_cache do
_cache[i] = nil
end
return _unpack(_cache)
end
local _pack2
_pack2 = function(i, a1, a2, ...)
_cache[i] = _floor(a1)
if a2 then
_pack2(i + 1, a2, ...)
end
end
function floor4(...)
local n = _select('#', ...)
_pack2(1, ...)
for i = n + 1, #_cache do
_cache[i] = nil
end
return _unpack(_cache)
end
function floor5(a1, a2, ...)
if a2 then return _floor(a1), floor5(a2, ...)
else return _floor(a1) end
end
local tests = 100000
local input = {}
for i = 1, tests do
input[i] = {}
for j = 1, math.random(1, 10) do
input[i][j] = math.random()*100
end
end
local t1, m1 = os.clock(), collectgarbage("count")
for i = 1, tests do
floor2(_unpack(input[i]))
end
local t2, m2 = os.clock(), collectgarbage("count")
for i = 1, tests do
floor3(_unpack(input[i]))
end
local t3, m3 = os.clock(), collectgarbage("count")
for i = 1, tests do
floor4(_unpack(input[i]))
end
local t4, m4 = os.clock(), collectgarbage("count")
for i = 1, tests do
floor5(_unpack(input[i]))
end
local t5, m5 = os.clock(), collectgarbage("count")
print(t2 - t1, m2 - m1)
print(t3 - t2, m3 - m2)
print(t4 - t3, m4 - m3)
print(t5 - t4, m5 - m4)
Running on
http://www.lua.org/cgi-bin/demo for 1-10 arguments:
Code: Select all
time:0.08 mem:14063.2890625 -- with the intermediate 'tbl', notice the memory usage
time:0.09 mem:1.453125 -- with select
time:0.08 mem:3.109375 -- with custom pack
time:0.08 mem:0 -- recursive, fastest for up to 10 arguments
and with 100 arguments:
Code: Select all
time:0.08 mem:16175.0625 -- with the intermediate 'tbl'
time:0.19 mem:2.0 -- with select, notice the slowdown from the many calls to "select"
time:0.13 mem:138.78125 -- with custom pack, probably the most 'balanced' result
time:0.15 mem:0 -- recursive
In conclusion, I would advise against functions with variable number of arguments in critical code,
including "math.max", "math.min" and "unpack"