-
- KeldorKatarn
- Posts: 243
- Joined:
Re: Help with avoiding memory allocations
I'm having my own issue with delegate allocation right now in another third party asset in Unity. It's one of those things in C# that's sometimes hard to avoid.
Maybe the delegates can be cached in the Extend class? Allocating them once is fine, just not again on every call.
Maybe the delegates can be cached in the Extend class? Allocating them once is fine, just not again on every call.
-
-
sfernandez
Site Admin
- Posts: 3363
- Joined:
Re: Help with avoiding memory allocations
The thing is that those delegates are created internally by the PInvoke code (by the C# marshaller), from a native funtion pointer.
To get rid of that internal allocation, I can only think on changing our code so it doesn't require a native function pointer to be passed to the C# callback. But it is not a trivial change, I need time to think about it.
To get rid of that internal allocation, I can only think on changing our code so it doesn't require a native function pointer to be passed to the C# callback. But it is not a trivial change, I need time to think about it.
-
- KeldorKatarn
- Posts: 243
- Joined:
Re: Help with avoiding memory allocations
Since these are base class callbacks, I assume they could be created once in the constructor and then stored for later? I'm confused why they need to get passed along on every function call anyway. They're base class implementations. Those remain constant over the object lifetime.
So what about creating getters for those callbacks, retrieve them once in the C# constructure, store them in fields and then access them from there in the changed Extend methods that get called without these callbacks? That would introduce additional fields on the Extend class and a bit of additional memory, but that way they would get allocated once and get stored over the object lifetime and not allocated as temporary instances on every call. Having the cost of delegate fields being in memoryover the lifetime is probably worth it over the allocation cost that comes with every call.
The problem I'm having specifically is that I use a control to render radar dots on a minimap. The position changes every frame so I'm rendering the dots in OnRender and just databind the collection. The alternative is do stuff with databinding templates and using Converters, but converters box value types like Point and Vector so that would allocate constantly.
So moving it to OnRender was intended to be a performance improvement, especially since rendering small circles is more efficient than actually having full datatemplates just for a dot. But.. because of the callbacks, OnRender is also allocating. Now I can reduce the framerate of the control to only call InvalidateVisual() every 2nd frame or so, to improve things a bit, but since I still need to continuously render these dots, I need to call OnRender for this one specific control basically every frame or so, which leads to the callback being allocated every frame as well.
I'm open to workaround ideas for this btw, as long as this i an issue. But I don't really know how else to render this efficiently.
So what about creating getters for those callbacks, retrieve them once in the C# constructure, store them in fields and then access them from there in the changed Extend methods that get called without these callbacks? That would introduce additional fields on the Extend class and a bit of additional memory, but that way they would get allocated once and get stored over the object lifetime and not allocated as temporary instances on every call. Having the cost of delegate fields being in memoryover the lifetime is probably worth it over the allocation cost that comes with every call.
The problem I'm having specifically is that I use a control to render radar dots on a minimap. The position changes every frame so I'm rendering the dots in OnRender and just databind the collection. The alternative is do stuff with databinding templates and using Converters, but converters box value types like Point and Vector so that would allocate constantly.
So moving it to OnRender was intended to be a performance improvement, especially since rendering small circles is more efficient than actually having full datatemplates just for a dot. But.. because of the callbacks, OnRender is also allocating. Now I can reduce the framerate of the control to only call InvalidateVisual() every 2nd frame or so, to improve things a bit, but since I still need to continuously render these dots, I need to call OnRender for this one specific control basically every frame or so, which leads to the callback being allocated every frame as well.
I'm open to workaround ideas for this btw, as long as this i an issue. But I don't really know how else to render this efficiently.
-
-
sfernandez
Site Admin
- Posts: 3363
- Joined:
Re: Help with avoiding memory allocations
Solved #3970 for 3.2.8 version.
Who is online
Users browsing this forum: No registered users and 2 guests