Help making my "orientation" module faster than roblox cframe

I dont have much currently but I’d like these functions to be faster than roblox’s so what can I do?

btw to make it faster I decided on having the orientations be non functional with explicit cloning

--[[
	Orientation
	
	it modifies the original matrix btw so use clone if u dont want that
	
--]]

-- Constants

-- cached
local unpack = unpack
local setmetatable = setmetatable

-- main

local Orientation

local function clone(o)
	return setmetatable({unpack(o)},Orientation)
end

local function components(o)
	return unpack(o)
end

local function inverse(o) -- https://en.wikipedia.org/wiki/Orthogonal_matrix
	local t = o[5]
	o[5] = o[7]
	o[7] = t
	
	t = o[6]
	o[6] = o[10]
	o[10] = t
	
	t = o[9]
	o[9] = o[11]
	o[11] = t
	
	return o
end

local function multO(a,b) -- modifies right (b)
	local bx = b[1]
	local by = b[2]
	local bz = b[3]
	
	local a00 = a[4]
	local a01 = a[5]
	local a02 = a[6]
	local a10 = a[7]
	local a11 = a[8]
	local a12 = a[9]
	local a20 = a[10]
	local a21 = a[11]
	local a22 = a[12]
	
	local b00 = b[4]
	local b01 = b[5]
	local b02 = b[6]
	local b10 = b[7]
	local b11 = b[8]
	local b12 = b[9]
	local b20 = b[10]
	local b21 = b[11]
	local b22 = b[12]
	
	b[1] = a[1] + a00*bx+a01*by+a02*bz
	b[2] = a[2] + a10*bx+a11*by+a12*bz
	b[3] = a[3] + a20*bx+a21*by+a22*bz
	
	b[4] = a00*b00+a01*b10+a02*b20
	b[5] = a00*b01+a01*b11+a02*b21
	b[6] = a00*b02+a01*b12+a02*b22
	
	b[7] = a10*b00+a11*b10+a12*b20
	b[8] = a10*b01+a11*b11+a12*b21
	b[9] = a10*b02+a11*b12+a12*b22
	
	b[10] = a20*b00+a21*b10+a22*b20
	b[11] = a20*b01+a21*b11+a22*b21
	b[12] = a20*b02+a21*b12+a22*b22
	
	return b
end

local function multV(o,v) -- modifies v
	local x = v[1]
	local y = v[2]
	local z = v[3]
	
	v[1] = o[1] + o[4]*x+o[5]*y+o[6]*z
	v[2] = o[2] + o[7]*x+o[8]*y+o[9]*z
	v[3] = o[3] + o[10]*x+o[11]*y+o[12]*z
	
	return v
end

local Orientation = {
	Clone = clone,
	Components = components,
	Inverse = inverse,
	MultO = multO,
	MultV = multV,
	
	__mul = multV,
}

Orientation.__index = Orientation

function Orientation.Identity()
	return setmetatable({
		0,0,0,
		1,0,0,
		0,1,0,
		0,0,1,
	},Orientation)
end

function Orientation.FromV(x,y,z)
	return setmetatable({
		x,y,z,
		1,0,0,
		0,1,0,
		0,0,1,
	},Orientation)
end

function Orientation.New(x,y,z,r00,r01,r02,r10,r11,r12,r20,r21,r22)
	return setmetatable({
		x,z,y,
		r00,r01,r02,
		r10,r11,r12,
		r20,r21,r22,
	},Orientation)
end

return Orientation

Using this test code:

local tick = tick
local count = 1000

do
	local Orientation = require(workspace.ModuleScript)
	local new = Orientation.New
	local inverse = Orientation.Inverse
	local mult = Orientation.MultO
	local unpack = unpack
	
	local x = new(CFrame.new(2,3,4,1,2,3,4,5,6,7,8,9):GetComponents())
	local y = new(CFrame.new(-2,-3,-4,-1,-2,-3,-4,-5,-6,-7,-8,-9):GetComponents())
	
	local start = tick()
	for i = 1,count do
		y=new(unpack(inverse(x)*inverse(y)))
		x = new(unpack(x))
	end
	print(tick()-start)
end

do
	local cf = CFrame.new
	
	local x = cf(2,3,4,1,2,3,4,5,6,7,8,9)
	local y = cf(-2,-3,-4,-1,-2,-3,-4,-5,-6,-7,-8,-9)
	
	local start = tick()
	for i = 1,count do
		x = x:inverse()
		y = cf((x*y:inverse()):GetComponents())
		x = cf(x:GetComponents())
	end
	print(tick()-start)
end

I get it being 0.5-2 times slower but if I up count to 100k it takes 1.8 times as long (.18 seconds vs .1 for roblox)

it’s a good exercise but why are you trying to beat out roblox’s that’s been heavily optimized already? are you doing something incredibly intensive or just having fun with a challenge?

1 Like

always gonna be for fun with a secret hope of it being useful

2 Likes

Aren’t the Roblox functions written in C++ which is on its own faster than Lua anyway?

yes but the fact that i got it to be this fast already means something

Alright well good luck then. I don’t know how you could make it faster.

You should avoid metamethod calls. Function calls in general are slow, and metamethods just add more function calls. Of course, that’s ignoring the fact that you did the same with the CFrame library. If you wanted to go all the way, you could eliminate function calls altogether and see what you get.

An interesting exercise would be to implement your orientations as quaternions internally, which have faster multiplication but are slower at transforming points.

2 Likes

After I do axis angle library im gonna do quaternion library

also I did a lot of benchmarking and metamethod calls were same speed for me as function calls
only __index is really slower but thats because its indexing and then calling a function (although its also slower than normal index but the idea is to cache the functions so it doesnt matter in my case)

1 Like

While I agree with the other posters that you won’t beat out Roblox in speed b/c it’s in C++ I have a few resources that I think you will find helpful!

Good luck!

7 Likes