I think I should stop looking into optimization but it seem like I have gone too far. Digging through luau performance site and posts on devforum again I found some more ways to optimizes some parts of your codes. Still you should consider if it worth implementing and sacrificing readability if the program need to be as blazingly fast to handle large amounts of operations.
Here are the results I gathered do notes that the comment --unstable meant that the function can result in faster operation but also slower operation
and the chance are varies
.
In my testing with my current specs i5-12400f and 3050 with standard ram amounts
and empty roblox baseplate
, the slow operation
seem to show at the 4-15th run
about 0.00001 ~ 0.0000098 slower than the other run
and fast operation
happens at ?-? run
, I think it rare
to happen but it once get to ~0.0000077
, better go with optimized version 5 (add5)
.
Testing outside of roblox environment
shows a different result maybe it because I have to create a mock up of vector3
, the optimized version 3 (add3) is faster
than the other. Although from luau v0.605
onward have let you to run luau-compile with --vector-lib
I still don’t know if I did it right and I don't know how to uses it anyways
.
So anyways here the codes that I used for testing and optimization, there methods like local xnil xnil = nil explained here and other recommended methods taken from the performance site in luau likes Creating and modifying tables using table.create, some unnecessary table index cleaning and reusing, opted into using if then expression to error than assert because of assert problem, going back into numeric loop because it faster and the amounts of elements is calculated and need to reuse for more optimization. Codes are run with --!native
and --!optimize 2
Roblox Studio Code:
--!native
--!optimize 2
local clock = os.clock
local am = 1000
local create = table.create
vector = {}
-- Add two vectors
function vector.add(v1, v2)
assert(#v1 == #v2, "Vectors must be of the same length.")
local result = {}
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
-- Add two vectors
function vector.add1(v1, v2)
assert(#v1 == #v2, "Vectors must be of the same length.")
local result = create(#v1)
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
-- Add two vectors
function vector.add2(v1, v2)
local v1A = #v1
assert(v1A == #v2, "Vectors must be of the same length.")
local result = create(v1A)
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
-- Add two vectors
function vector.add3(v1, v2)
local v1A = #v1
if v2[v1A + 1] then error"" end
local result = create(v1A)
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
local xnil xnil = nil
-- Add two vectors
function vector.add4(v1, v2)
local v1A = #v1
if v2[v1A + 1] then error"" end
local result = create(v1A, xnil)
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
-- Add two vectors
function vector.add5(v1, v2)
local v1A = #v1
if v2[v1A + 1] then error"" end
local result = create(v1A, xnil)
for i = 1, v1A do
result[i] = v1[i] + v2[i]
end
return result
end
local ind = 1
-- Add two vectors
function vector.add6(v1, v2)
local v1A = #v1
if v2[v1A + 1] then error"" end
local result = create(v1A, xnil)
for i = ind, v1A do
result[i] = v1[i] + v2[i]
end
return result
end
-- Add two vectors
function vector.add7(v1, v2) -- unstable
local v1A = #v1
if v2[v1A + ind] then error"" end
local result = create(v1A, xnil)
for i = ind, v1A do
result[i] = v1[i] + v2[i]
end
return result
end
-- Add two vectors
function vector.add8(v1, v2) -- unstable
local v1A = #v1
if v2[v1A + ind] then error"" end
local result = create(v1A, xnil)
for i = ind, v1A do
result[i] = v1[i] + v2[i]
end
return result
end
local random = math.random
local v1 = create(am, Vector3.new(random(),random(),random()))
local v2 = create(am, Vector3.new(random(),random(),random()))
print("og")
local elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op1")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add1(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op2")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add2(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op3")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add3(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op4")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add4(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op5")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add5(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op6")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add6(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op7")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add7(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op8")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add8(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
VS-Code:
--!native
--!optimize 2
local clock = os.clock
local am = 1000
local create = table.create
vector = {}
-- Add two vectors
function vector.add(v1, v2)
assert(#v1 == #v2, "Vectors must be of the same length.")
local result = {}
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
-- Add two vectors
function vector.add1(v1, v2)
assert(#v1 == #v2, "Vectors must be of the same length.")
local result = create(#v1)
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
-- Add two vectors
function vector.add2(v1, v2)
local v1A = #v1
assert(v1A == #v2, "Vectors must be of the same length.")
local result = create(v1A)
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
-- Add two vectors
function vector.add3(v1, v2)
local v1A = #v1
if v2[v1A + 1] then error"" end
local result = create(v1A)
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
local xnil xnil = nil
-- Add two vectors
function vector.add4(v1, v2)
local v1A = #v1
if v2[v1A + 1] then error"" end
local result = create(v1A, xnil)
for i, value in ipairs(v1) do
result[i] = value + v2[i]
end
return result
end
-- Add two vectors
function vector.add5(v1, v2)
local v1A = #v1
if v2[v1A + 1] then error"" end
local result = create(v1A, xnil)
for i = 1, v1A do
result[i] = v1[i] + v2[i]
end
return result
end
local ind = 1
-- Add two vectors
function vector.add6(v1, v2)
local v1A = #v1
if v2[v1A + 1] then error"" end
local result = create(v1A, xnil)
for i = ind, v1A do
result[i] = v1[i] + v2[i]
end
return result
end
-- Add two vectors
function vector.add7(v1, v2) -- unstable
local v1A = #v1
if v2[v1A + ind] then error"" end
local result = create(v1A, xnil)
for i = ind, v1A do
result[i] = v1[i] + v2[i]
end
return result
end
-- Add two vectors
function vector.add8(v1, v2) -- unstable
local v1A = #v1
if v2[v1A + ind] then error"" end
local result = create(v1A, xnil)
for i = ind, v1A do
result[i] = v1[i] + v2[i]
end
return result
end
local random = math.random
local vectorMockmt = {
__add = function(v1, v2)
return setmetatable({ x = v1.x + v2.x, y = v1.y + v2.y, z = v1.z + v2.z }, getmetatable(v1))
end
}
local vectorMock1 = setmetatable({ x = 1, y = 1, z = 1}, vectorMockmt)
local vectorMock2 = setmetatable({ x = 1, y = 1, z = 1}, vectorMockmt)
local v1 = create(am, vectorMock1) --Vector3.one)
local v2 = create(am, vectorMock2) --Vector3.one)
print("og")
local elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op1")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add1(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op2")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add2(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op3")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add3(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op4")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add4(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op5")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add5(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op6")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add6(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op7")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add7(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
print("op8")
elapsed = 0
for i = 1, am do
local start = clock()
local _ = vector.add8(v1,v2)
local endT = clock() - start; elapsed = elapsed + endT
end
print(elapsed/ am)
Some miscellaneous stats:
compiled code using --text
from luau-compile
text.txt (15.6 KB)
stats using --record-stats=total
from luau-compile
. In code, variable am
is changed to 1
stats.json (515 Bytes)
coverage using --coverage
from luau
coverage.txt (2.0 KB)
profile using --profile
from luau
consider turning it to svg from the tools folder using perfgraph.py
profile.txt (1.4 KB)
No microprofiler because I am just not to be able to record it or really can know where my scripts are. All ran with luau v0.606
Some more recommendation optimization consider implementing parallel luau and uses some parallel luau module am using promise based threader for some of my project.
Also I think I have found a things to do with this maybe with AI or large datasets of vectors that maybe use for procedural animation trying to remake the thing from uncharted but I am not gonna do it anytime soon, some more notes here don’t take my information only and make sure to take information from many sources or sources that you trust and then test and trials and errors with it.