#Garbage collection of event Action

1 messages · Page 1 of 1 (latest)

loud copper
#

So I have MonoBehaviour object which is manager, there are many dynamic objects which need to be called every frame (Update). Those objects are pooled and when they are in pool they are not part of the Update calls.

So my manager has an event field "internal event Action OnUpdate;"

Every object that needs update subscribes to the event and unsubscribes upon being returned to the pool.

Of course every Update I call "OnUpdate?.Invoke();"

My question is do I need to worry if its about 100-200 objects? Is there more performant way to do this?
ChatGPT is saying that calling += and -= creates lots of garbage if called often and that I should change it to the List<Action> which doesnt seem right.

mild ermine
#

I don't think there will be any noticeable overhead of running one variant or another, as 200 objects are not that many, and in the end calling += and -= on Action should just be adding another delegate to its internal list
but for a definitive answer there's no way around actually benchmarking it
you can use the test runner for performance benchmarks (https://docs.unity3d.com/Packages/com.unity.test-framework.performance@3.2/manual/index.html) and you can also check GC usage (https://docs.unity3d.com/Packages/com.unity.test-framework@2.0/api/UnityEngine.TestTools.Constraints.AllocatingGCMemoryConstraint.html)

tepid shore
#

A list of actions is indeed superior if you are constantly adding and removing listeners. There is an important caveat, though: you cannot subscribe or unsubscribe while iterating over the list.

With delegate types, you can safely do this.

#

See how much garbage is getting generated (and compare that to the overall amount of garbage being allocated) before doing anything, though.

tepid shore
tardy slate
#

You can always iterate through your objects and just call their methods istead of subscribe desubscribe to the action.

hollow geyser
#

You should absolutely do what hunter proposes. Using an event for what you’re doing is entirely backwards if your manager truly is supposed to be a manager. A component should not observe its manager, it is commanded by its manager to execute an update. The decoupling introduced by the event is wasted, makes everything harder to debug and extend when future optimizations are needed.

loud copper
tepid shore
#

Yeah, almost all of my "manager" objects store lists of things to invoke methods on, rather than having a public event.

Random objects have no business subscribing to a manager's "update" event

#

Events make a lot more sense if a variety of things need to be notified about something

oak kayak
oak kayak
#

you're looking for performant way but you're using delegate. That sounds off bcos multicast delegate will always need to reiterate the internal array each time you invoke them

oak kayak
hollow geyser
#

And actual performance optimization will be impossible when unstructured delegates are involved as they will be impossible to iterate in a cache efficient way. Consequently, if you may ever need advanced optimizations in a system: Avoid event/observer patterns to make later rewrites simpler (no fundamental architecture changes).

mild ermine
oak kayak
#

as said, delegates are immutable in c#

#

you can just search what immutable means there