• Subject: Re: Ideas for faster math in lua
• From: David Manura <dm.lua@...>
• Date: Thu, 14 Feb 2008 19:11:15 +0000 (UTC)

```Niklas Frykholm writes:
> I would like to be able to process lots of small mathematical objects
> (vector3 and quaternions) in a resource constrained environment
> (computer game), without having to pay the cost of new-ing and garbage
> collecting them. ... So here are some ideas...

If you're willing to sacrifice the first-classness of these objects, some macro
processing can translate them into local variables on the stack[1].

local lua = [[
-- typical implementation (without filtering)
local function cross_vector2(u, v, result)
local u1, u2, u3 = u[1], u[2], u[3]
local v1, v2, v3 = v[1], v[2], v[3]
result[1], result[2], result[3] = u2*v3-u3*v2, u3*v1-u1*v3, u1*v2-u2*v1
return result
end

-- test and benchmark
local function benchmark(func)
local t1 = os.clock()
func()
local t2 = os.clock()
print("time:", t2-t1)
end
benchmark(function()
local vector u = 1, 0, 0
local vector v = 0, 1, 0
for n = 1,5000000 do
cross_vector(u,v,u)
--print("DEBUG: u=" .. stringify_vector(u))
end
end)
benchmark(function()
local u = {1, 0, 0}
local v = {0, 1, 0}
for n = 1,5000000 do
cross_vector2(u,v,u)
-- print("DEBUG: u=" .. table.concat(u, ', '))
end
end)
]]

-- source filtering implementation
lua = string.gsub(lua,
"local%s+vector%s+(%w+)%s*=%s*(%w+)%s*,%s*(%w+)%s*,%s*(%w+)",
"local %1_1, %1_2, %1_3 = %2, %3, %4")
lua = string.gsub(lua,
"cross_vector%s*%(%s*(%w+)%s*,%s*(%w+)%s*,%s*(%w+)%s*%)",
"%3_1, %3_2, %3_3 = " ..
"%1_2*%2_3-%1_3*%2_2, %1_3*%2_1-%1_1*%2_3, %1_1*%2_2-%1_2*%2_1")
lua = string.gsub(lua,
"stringify_vector%((%w+)%)", "(%1_1 .. ',' .. %1_2 .. ',' .. %1_3)")

-- source filter
print("DEBUG[\n" .. lua .. "]")

Results on one system with Lua 5.1:

time: 0.937
time: 4.078

or with LuaJIT 1.1:

time: 0.141
time: 0.593

[1] http://lua-users.org/wiki/SourcePreprocessing

```