Well, I prefer X += Y instead of X = X + Y. It is less to type, a smaller formula, and it just makes your scripts neater anyway. Plus, sense it indexes once I believe it is faster (it may not sense its running through Syntax sugar).
If you really want to do it then just do it, youâll be happier.
But I like micro-optimizing!! (As I said before it only takes me 5-10 minutes.) Plus if your indexing something wouldnât it be faster to only index that once instead of twice?
You wouldnât get any tangible benefit from doing it, just donât. If you want to switch for convenience sake go ahead, but as mentioned there wonât be any meaningful boost, if any. You should only optimize the parts of your code that need optimizing, not doing it just for the sake of doing it. You know the saying âif it ainât broke donât fix itâ, the same applies here. If it ainât need optimizing donât optimize it.
Itâs also unlikely that the way you increment your variable is your bottleneck.
You can benchmark it yourself using os.clock as it is itâs intended purpose.
-- Record the initial time:
local startTime = os.clock()
-- Do something you want to measure the performance of:
local a = 0
for i = 1, 5000000 do
a += 1
end
-- Measure amount of time this took:
local deltaTime = os.clock() - startTime
print("Elapsed time shorthand syntax:" .. deltaTime)
-- Record the initial time:
local startTime = os.clock()
-- Do something you want to measure the performance of:
local a = 0
for i = 1, 5000000 do
a = a + 1
end
-- Measure amount of time this took:
local deltaTime = os.clock() - startTime
print("Elapsed time not shorthand syntax: " .. deltaTime)
16:33:27.637 Elapsed time shorthand syntax:0.024885643000744 - Server - Script:10
16:33:27.661 Elapsed time not shorthand syntax: 0.024271065998619 - Server - Script:21
Currently getting results similar to @imKirda 0.0006 second difference for 5000000 iterations so itâs like 0.0006/5000000 which is 0.12 nano seconds slower. Itâs probably inacurate because os.clock is only precise down to a microsecond which is 0.000001 seconds and it depends on how fast my computer is running it I believe. Of course, itâll very but the difference in time is not significant at all waste of time as @incapaz mentions yet itâs very interesting.
I could be entirely wrong on this, but IIRC, Iâve read somewhere that in some use cases, using += is faster than using something like:
local a = 0
while wait(1/30) do
a = a + 1
end
What I mean by this is the idea of overhead via metatables and/or functions. Think indexing a table that has a really complex metastructure that goes through indexing even more tables and maybe calling some internal function(s). This is where you could see at least (?) twice the gain in speed.
From a face value, no - doing something like this wonât get you any worthwhile speed boost:
local a = 0
while wait(1/30) do
a += 1
end
But if there was overhead to indexing a variable through a table, like nested metatable usage or function calls, then I believe that the overhead would be a detriment to the speed, having to essentially do all the work almost twice just for a read-only value.
Edit: I forgot to explain why I believe itâd be faster from Robloxâs internal perspective:
It would be faster because Roblox would internally cache both the pointer in memory to the table value as well as the returned value itself when specifically using += and use both to both set the value in memory as well as return whatever that would be plus whatever constant youâve specified.
@hello42 is correct in their assessment, and I believe ROBLOX even stated this officially when they ported the syntax over, but your infrastructure would need to be pretty intense to begin with before youâd see anything meaningful. Like, extremely intense.
This example is very similar to @dthecoolestâs benchmark example, and it shows similar results despite involving a (fairly arbitrary) metatable structure.
local nest_base = {a=1}
local nest_tables = {}
nest_tables[1] = setmetatable({},nest_base)
nest_tables[1].__index = nest_base
for i=1,25 do
local new_nest = setmetatable({},nest_tables[i])
new_nest.__index = getmetatable(new_nest)
nest_tables[i + 1] = new_nest
end
local nested_table = nest_tables[#nest_tables]
local start = os.clock()
for i=1,100000000 do
nested_table.a = nested_table.a + 1
end
print(os.clock() - start) --Takes 1.55 seconds on average
nested_table.a = 1
start = os.clock()
for i=1,100000000 do
nested_table.a += 1
end
print(os.clock() - start) --Takes 1.55 seconds on average
local nests = 0
local last_nest = getmetatable(nested_table)
while last_nest do
nests += 1
last_nest = getmetatable(last_nest)
end
print(nests) --Prints 26; that is, 26 metatable layers
So, as you can see, even at 26 layers deep, there is no meaningful time savings from either syntax. Granted, this calculation is only a simple iteration without too much going on, but the point still stands that the usage of the syntax should predominantly come down to personal preference.
Ultimately, though, and this is true even to some extent of practices with noticeable performance impact, the goal should be to write legible code. Saving a few nanoseconds in runtime isnât worth not knowing what your code is doing when you leave it on the back burner for 6 months and then finally come back to it. I know the â+=â versus â= +â syntax variation isnât necessarily going to bring about that much confusion, but you should keep this mantra in the back of your mind when writing code.
So glad someone made a way more elegant looking code solution than I did from my tests!
I also found similar results with just nested tables.
all values looped to the 5,000,000th
a is the control, a non-nested local variable
a += 1, (0.020683000002464 seconds)
a = a + 1 (0.020264799997676 seconds)
delta: 0.000418200004788 (negligible?)
t is a nested table to the 20th degree
t{20} += 1, (0.50851189999958 seconds)
t{20} = t{20} + 1, (0.87945169999875 seconds)
delta: t{20} += is 0.37093979999917 (~42.17% faster)
Comparing the data from five hundred thousand iterations to five million, the numbers just seem to factor up by 10, so at some point there is a taper off to how much more performant things get between the two methods. However, this also factors down when the nesting isnât so large, if for example, the table was instead nested to the 19th degree. And that disparity goes all the way down as the nesting becomes less and less.
Itâs sort of become a different question now, but I believe += has itâs place, and for most things, just + is probably just fine, and either may just be personal preference for the writer.
According to the assessment, it is merely a microoptimization and should only be considered as in the final decision. Thus meaning that you donât necessarily have to optimize every single syntax that exists. The only time you would do the microoptimization is when the game is nearly finished. Run an A/B test to check whether something is better than the other.
Some microoptimizations are just sugar syntax as previously mentioned and only makes it âeasierâ to read. Sometimes the contrary. It is just elegant.
Is it faster? I donât know. Other people have answered that question.
I can tell you that worrying about speed is worse than just a huge waste of your time. The people that advocate for doing stuff like x += y over x = x + y on the count of it being âfasterâ are outright infuriating. Little Joey isnât going to stop playing your game because something lags 0.0000001 seconds behind â something literally thousands of times beyond human perception itself. In cases like these, do it because it makes your code easier to maintain, not because of performance.
Usually I only worry about performance if it has a notable impact on a small scale, as in it doesnât require running it half a million times to actually get something the Lua VM can even count in the first place.
In my opinion, the sort of stuff you should worry about in raw Luau (granted, under circumstances where you can avoid these) is:
There isnât really a performance boost, you can test this out your self. Itâs just better to keep your code small and organizable so value += n is preferred over value = value + n.