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

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.

You should change the title from "SetAttribute is highly unoptimized for usage in loops" to something that better conveys the overall gist of this thread.

To reiterate from my first post, the gist of this thread is:

So a title that’d be more suitable would be:
"PSA: Why you shouldn't store frequently mutated state through instances"

1 Like

Most likely due to the replication overhead. You’ll also see a reduction in network send/recv.

Rule of thumb is to not use them if not everyone has to see the data. Usually only one player needs to see the data, so a custom replication system is better.

I do think the tutorial is nice but this is a known fact, as said before indexing a raw-memory dictionary is going to be exponentially faster than what Roblox does which is fetch the memory address of the property by indexing the instance, then read it, then return it.

This is why we need a guide explaining common code standards and efficient methods of storing data.

Sorry to bump this thread, but I want to provide more context to the test in the original post as its a bit biased towards a single use-case and a tad misleading. I don’t disagree with the opinion of the original poster, but I have different reasons for using alternatives to SetAttribute.

The test in the original post assumes that the data you are setting / using only exists on the server, in which case yes, storing data in a table would be the fastest and most efficient method. However, SetAttribute comes with a caveat, and that is the fact that setting an attribute on the instance replicates to the clients - just like any other property on an instance would. So let’s say you want to use this stored information on the client for display purposes. The correct code snippet that compares both SetAttribute and the table storage with RemoteEvents for network replication would actually look more like the following…

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
	game.ReplicatedStorage.RemoteEvent:FireAllClients({
		health = AmazingDictionary.Health
	})
	AmazingDictionary.Speed = i
	game.ReplicatedStorage.RemoteEvent:FireAllClients({
		speed = AmazingDictionary.Speed
	})
end

print(os.clock() - DictionaryTime)

Doing this we see that SetAttribute is around 30ms and table with RemoteEvents is around 55ms.

for i = 1,10000 do
	AmazingDictionary.Health = i
	AmazingDictionary.Speed = i
		
	game.ReplicatedStorage.RemoteEvent:FireAllClients({
		speed = AmazingDictionary.Speed,
		health = AmazingDictionary.Health
	})
end

Further optimizing the RemoteEvents method to combine all property changes into a single RemoteEvent call reduces the time to about 30ms, the same as two SetAttribute calls. Which means that RemoteEvents become more efficient as more data is combined into a single network call (given the amount of data being set in both methods is the same size).

So in conclusion, don’t use SetAttribute if your plan is to only use the values on the server and you’re doing this in large quantities. It is creating needless network events which will start to cause network bottleneck, and eventually FPS drops. Small quantities of SetAttribute is negligible and will cause no noticeable impact to your game’s network performance. If you plan to utilize this data on the client in some way, it would be acceptable to use SetAttribute for a small quantities of values (e.g. health, speed, damage, state), but anything over 3-4 will start to show a noticeable difference when compared to RemoteEvents. Personally, I prefer RemoteEvents as they are more customizable with who the data is replicated to, but SetAttribute can be a convenient and easy alternative in the right circumstances.

4 Likes