Faster Math in Roblox

Hello! I’ve made a few projects that required a lot of math which would be called many many times and would even drop FPS at certain times, while I was doing this I was curious to see how efficient and optimized the Math library truly was so I tried recreating it and the results were not looking great on Roblox’s side

If anyone is going to be using a lot of math and want to optimize it or even micro-optimize it if you aren’t using it a lot then this is the place for you. It may be a bit messy if you are going to use it but the performance is about 50% - 25% better
(I recommend using this only if you are going to use it many many many times in a script (millions of times) )

You could put this in a module script but I found out that the results were slower if it was in a module script, I might have done something wrong though as I barely use them so you can give it a shot

math.floor(Number) = Number - Number % 1
math.round(Number) = Number + 0.5 - (Number + 0.5) % 1)
math.ceil(Number) = Number + 0.9  - (Number + 0.9) % 1

math.fmod(Number) = Number % 1
math.abs(Number) = ((Number)^2)^0.5 (by absentdenik)

math.pi = 3.141592653589793
math.huge = 1/0

math.rad(Number) = Number * 0.0174532925
math.deg(Number) = Number * 57.2957795131
6 Likes

math.abs(Number) = (Number^2)^0.5

1 Like

After comparing math.abs difference, there are the results so far

--Script used to test
local orig = 0
for i = 1, 10000 do
    local s = os.clock()
    local Number = -5
    local a = math.abs(Number)
    local e = os.clock()
    orig += e-s
end
orig = orig/1000

task.wait(0.5)

local cus = 0
for i = 1, 10000 do
    local s = os.clock()
    local Number = -5
    local a = Number < 0 and -Number or Number
    local e = os.clock()
    cus += e-s
end
cus = cus/1000

task.wait(0.5)

local cus2 = 0
for i = 1, 10000 do
    local s = os.clock()
    local Number = -5
    local a = (Number^2)^0.5
    local e = os.clock()
    cus2 += e-s
end
cus2 = cus2/1000

print(`\nOriginal >>> {orig}\nCustom1 >>> {cus}\nCustom2 >>> {cus2}`)```

I edited the post to have your version as it is much cleaner at the cost of very little performance

as at the end of the day it is still 50% better than the math.abs one

1 Like

As a form of a modulescript.

local mathlib = {}

function check(num)
	if type(num) ~= "number" then warn(tostring(num).. " is not a number") return false end
end

function mathlib.pi()
	return 3.141592653589793
end
function mathlib.huge()
	return 1/0
end
function mathlib.round(num)
	if check(num) then
		return num >= 0 and num + 0.5 - (num + 0.5) % 1 or num + 0.5 - (num - 0.5) % 1
	end
end
function mathlib.abs(num)
	if check(num) then
		return (num^2)^0.5
	end
end
function mathlib.fmod(num)
	if check(num) then
		return num % 1
	end
end
function mathlib.ceil(num)
	if check(num) then
		return num + 1 - num % 1
	end
end
function mathlib.floor(num) 
	if check(num) then
		return num - num % 1
	end
end
return mathlib

1 Like

The problem is that with a module script this is severely slower than the built in functions

2 Likes
Code
local nums = table.create(1e6)
for i = 1, 1e6 do
	nums[i] = math.random()
end

local s = os.clock()
for i = 1, 10 do
	for _, num in nums do
		local v = math.floor(num)
	end
end
print("math.floor", os.clock() - s)

local s = os.clock()
for i = 1, 10 do
	for _, num in nums do
		local v = num - num % 1
	end
end
print("math.floor alternative", os.clock() - s)


local s = os.clock()
for i = 1, 10 do
	for _, num in nums do
		local v = math.round(num)
	end
end
print("math.round", os.clock() - s)

local s = os.clock()
for i = 1, 10 do
	for _, num in nums do
		local v = num >= 0 and num + 0.5 - (num + 0.5) % 1 or num + 0.5 - (num - 0.5) % 1
	end
end
print("math.round alternative", os.clock() - s)


local s = os.clock()
for i = 1, 10 do
	for _, num in nums do
		local v = math.rad(num)
	end
end
print("math.rad", os.clock() - s)

local s = os.clock()
for i = 1, 10 do
	for _, num in nums do
		local v = num * 3.141592653589793 / 180
	end
end
print("math.rad alternative", os.clock() - s)


local s = os.clock()
for i = 1, 10 do
	for _, num in nums do
		local v = math.deg(num)
	end
end
print("math.deg", os.clock() - s)

local s = os.clock()
for i = 1, 10 do
	for _, num in nums do
		local v = num * 180 / 3.141592653589793
	end
end
print("math.deg alternative", os.clock() - s)

math.floor, math.round, and math.rad are faster
the custom math.deg is 5-10% faster
image

I don’t think Number + 1 - Number % 1 is correct
image

Neither is (Number^2)^0.5
image

1 Like
  • hmm thats strange as when I tested it i got better results but I also didnt test it on random numbers such as you so that might be it

  • i did fix math.round and now it should be faster

  • i’ll try fixing math.ceil

  • (Number^2)^0.5 does work but only on variables, i honestly dont know why but ig luau is just like that


I think it’s parsed as -(n^2)^0.5

From the replies the results are almost exactly the same. In addition, you guys don’t store a local reference to the function so your comparisons aren’t good.

Edit:
@RickAstll3y pointed out a change in Luau I didn’t know about that optimizes builtin functions.

1 Like