This tutorial is meant to cover a more basic form of optimizing of code that can be done to code without making it hard to read. This is NOT advanced level optimization, which is also a topic I can’t easily do. I will leave it up to someone like AxisAngle to do that one.
So, let us start with two basic questions. 1. “What is optimization?” and 2. “Why optimize?”. To start, optimizing is defined as to ”make the best or most effective use of”. Simply put, to make code run faster. This runs into the second question of why. The answer is pretty much in the definition, to make code run faster. Not everyone has a high end quad core i7 CPU and a NVIDIA GTX GPU, and in those cases a little bit of optimizing can make things run a lot smoother.
1. Use Local Variables
One of the most simple things you can do is add 6 characters to the beginning of your variables, and that is “local “. When you put local in front of a variable name, you are declaring a value as local, meaning it can only be used in the given scope (see example), but is faster than searching the “global” table because it has a lot of other things, including native Lua variables and ROBLOX functions and userdata.
So, How do I use local variables? Here is an example using global variables:
This = 1 --Declares a global value of This for i = 1, 5 do This = This * i --References the global value This, multiplies it by i --i can only be referenced in this scope because it is a local value end
Here is an example of local values:
local This = 1 --Declares a local value of This for i = 1, 5 do This = This * i --References the local value This and multiplies it by i end
Is that it? Actually, no. You can localize your functions too! How about some code to explain how.
--So let’s say you have this: function This() --Stuff end --Lets re-write it so it sets This as a global value: This = function() --Stuff end --See where this is going? local This = function() --Stuff end
2. Don’t Re-Do The Same Math When Needed
This isn’t the best subtitle, so an analogy would help. Let’s say you needed to do math starting with needing sin(0). You start by entering it into your calculator and see it is 0. Then you needed to add a number to it. If you wanted to save time, you would just input the last value rather than re-type sin(0). Not the best example, so here is code to help.
Here is what happens if you repeat the same operation for to make a part rise at a constant rate.
for i = 1, 50 do Part.CFrame = Part.CFrame * CFrame.new(0,1,0) wait() end
Now let’s write down what it does:
For 50 times…
1. Get the Part’s CFrame
2. Find the global value for CFrame
3. Create the new userdata for CFrame.new(0,1,0)
4. Multiply the Part’s CFrame from 1 to the CFrame from part 3
5. Set the Part’s CFrame from 4
6. Wait for 1/30th of a second
So, how can you optimize this?
local UpCFrame = CFrame.new(0,1,0) for i = 1, 50 do Part.CFrame = Part.CFrame * UpCFrame wait() end
Now what does it do?
A. Find the global value for CFrame
B. Create the new userdata for CFrame.new(0,1,0)
For 50 times…
1. Get the Part’s CFrame
2. Multiply the Part’s CFrame from 1 to the CFrame from part B
3. Set the Part’s CFrame from 2
4. Wait for 1/30th of a second
And just like that, you reduced 2 (really 3) steps that is done 50 times.
3. Reduce Indexing Of Tables
A while ago, AxisAngle talked about how he could cast thousands of rays per second with no performance hit, and this is a massive helper for that. There is a more complex explanation about that involving MetaTables, but let’s keep it simple.
for i = 1, 10 do game.Workspace:FindPartOnRay(Ray.new(Vector3.new(0,0,0),Vector3.new(0,i,0)) end
This may seem simple, but it is a lot more complex once you see all the steps it requies.
For 10 times...
1. Call __index (a MetaTable function) in game to get Workspace, and calling functions like this is fast but can stack if it called a lot to be slow.
2. Call __index in Workspace to get FindPartOnRay. Now to get the Ray.
3. Call __index for the global value new in Ray. Now to get the Vector3s.
4. Call __index for the global value new in Vector3.
5. Create the first vector from the function returned from 3 to create a Vector3 with the coordinates of 0,0,0.
6. Call __index for the global value new in Vector3.
7. Create the second vector from the function returned from 6 to create a Vector3 with the coordinates of 0,i,0.
8. Pass those arguments into the function returned in step 3 with the Vector3s from 5 and 7 to get the Ray
9. Pass those arguments into the function returned in step 8 into FIndPartOnRay
Long list, right? Now to use local values to lower the amount of times everything is indexed.
local Workspace = game.Workspace local FindPartOnRay = Workspace.FindPartOnRay --This is how you index a function without calling it. local Raynew,Vector3new = Ray.new,Vector3.new local Center = Vector3new(0,0,0) for i = 1, 10 do --For a function indexed by :, you have to pass the table it is part of first before the rest of the arguments. FindPartOnRay(Workspace,Raynew(Center,Vector3new(0,i,0)) end
A. Call __index in game to get Workspace
B. Call __index in Workspace to get FindPartOnRay
C. Call __index for the global value new in Ray.
D. Call __index for the global value new in Vector3.
E. Create a Vector with the function returned from D to create a blank Vector
For 10 times…
1. Create the second vector from the function stored in D to create a Vector3 with the coordinates of 0,i,0.
2. Reference the first vector from E and create the Ray from function stored in C
3. Pass the table the FindPartOnRay function is from (Workspace, so A) into the stored function in B with the Ray from 3.
How Do I Test The Speed Of My Code
This may seem complex at first, but it is simple, store the tick() of the start, run the code a given amount of times in a for loop, then subtract the new tick() from the first.
local function TestFunction() --Insert the code to tesst end local Start = tick() --Start time in seconds for i = 1, 1000 do --For 1,000 times... TestFunction() --Call TestFunction End print(tick()-Start) --End time in seconds
Doing these should make your code run faster. For example, when I did the 3rd optimization tip on the CameraScript, it went from 3%-5% in script performance to 0.5%-2%, and that is on Intel Core i7 4700MQ @ 3.25 GHz with TurboBoost. Optimization. Use it. Think about the people using toasters.
Bonus: With all of my tutorials, an image of the full tutorial for public is included.