Why storing constantly changing data on parts using attributes is a bad idea

Hello, I was trying to optimize my enemy system for my TD game and while i was commenting out lines of code in my system i discovered that just by commenting out 2 lines of code that had SetAttribute in them made my FPS increase from 50 for 2000 enemies to 73!

So i decided to benchmark SetAttribute vs Setting a value in a dictionary and i discovered that SetAttribute is quite bad to use repeatedly and these are the results i got for changing 10000 values:

Attributes: 0.016~ seconds
Dictionary: 0.00006~ seconds
image

And this is the code i used:

local AmazingDictionary = {
	Health = 0,
	Speed = 0,
}
local AttributeHolder = Instance.new("Part",workspace)

local AttributeTime = os.clock()
for i = 1,10000 do
	AttributeHolder:SetAttribute("Health",i)
	AttributeHolder:SetAttribute("Speed",i)
end
print(os.clock() - AttributeTime)

local DictionaryTime = os.clock()

for i = 1,10000 do
	AmazingDictionary.Health = i
	AmazingDictionary.Speed = i
end

print(os.clock() - DictionaryTime)

I decided to make this post just as a heads up for anyone wanting to optimize their game.
(also i am not sure if i put this post under the correct topic, so if i did put it under the wrong topic please tell me!)

30 Likes

Thank you, this should really be talked about more. I just applied this to my own entity system and I went from 40 FPS on 1.2K enemies to 60 FPS! Bravo Omrez!

5 Likes

may you include numbervalue into benchmark? im curious to see the result
although i am surprised attributes are far more unoptimized to overwrite than a dictionary

Sure i can test it out when im home!

Well i tested it out and these were the results:

0.00006~ for dictionary
0.00253~ for number value
image

seems like number value is better than attributes but is still slower than just using a dictionary

3 Likes

put it in three backticks (located under the escape button

You need to format the post better

also I tested the results using the benchmarker plugin and it’s correct

1 Like

The difference is that one has a function call overhead, and the other doesn’t. Performance is negligible enough that it shouldn’t matter.

5 Likes

Oh alright thank you! I didn’t know

1 Like

Well if you are using it every once and a while of course it won’t effect much performance wise, but i mainly made this post just to give a heads up for people who use attributes in while or run service loops

I think something similar to BulkMoveTo which CFrames a table of parts and doesn’t fire any events (like changed) but for attributes (BulkSetAttribute maybe?) would improve this. Of course its a pretty rare situation where you’re setting this many attributes.

I don’t think setting attributes would ever be more performant than just setting the value in a dictionary, just because of the events fired and overhead.

2 Likes

I don’t really see what you are trying to prove here. Of course indexing a dictionary would be faster than acquiring metadata.

The main purpose of attributes is to save data that is replicated.

Attributes are not MEANT for constant updates.
They function the best when updated occasionally rather than constantly.

4 Likes

Where is this from, how do I get this plugin?

2 Likes

I wasn’t trying to prove anything, Just wanted to make this post to tell people so they can know about this in the future.

Who would call set attributes 20,000 times in a single loop lmao, hmm yes let me just summon 20,000 event signals thats DEFINITELY good for performance :DDDDDDDD.

3 Likes

my alternative to this is create a dictionary using GetAttributes() and then updating the dictionary when the attribute is changed, might be convoluted but i idk
misread the setAttribute

i would and also we do not care

1 Like

Summary of thread:

Original post:

A devforum user arrives at the conclusion that storing frequently mutated state through instances is bad.

Replies:

And the crowd goes wild.

3 Likes

I believe the intention of this benchmark is to serve as an accurate simulation of the performance overhead of systems written by those who methodically neglect favorable design choices.


Performance is proportional to the design quality of a system, not the luau VM.

1 Like

Well, when i was first making my system i wasn’t aware of these things. I only learned about this when you made this comment. At the end of the day we all learn from mistakes, That is what programming is all about isn’t it? Sure, to you this seems stupid but with my experience it wasn’t. At the end of the day we all act and learn.