-
- KeldorKatarn
- Posts: 239
- Joined:
Help with avoiding memory allocations
Hi, I need some help in the hope to get rid of some memory allocations, if possible.
I see some happening here during measure and arrange and I'm not sure what's causing them:
Might be related to this custom panel (just there to overlay things and meant to be more lightweight than Grid)
Also I see some more allocations here related to PropertyChanged. Is this a boxing issue?
I have a notifying property of type Bracket, which is a Struct containing a Point, a Size and a bool.
Am I seeing these GetPropertyValue allocations because the structs get boxed? Can I avoid that somehow?
Also, I'm guessing feeding a Value Type into a IValueConverter will also always lead to boxing? For WPF it's fine but I'd love to avoid them in Unity if at all possible.
Also what's the Dictionary being used here?
I see some happening here during measure and arrange and I'm not sure what's causing them:
Might be related to this custom panel (just there to overlay things and meant to be more lightweight than Grid)
Code: Select all
/// <summary>A panel that stacks all its children on top of each other, letting them overlay each other.</summary>
public class OverlayStackPanel : Panel
{
public OverlayStackPanel()
{
Loaded += OnLoaded;
}
#if UNITY_5_3_OR_NEWER
private List<UIElement> InternalChildren { get; set; } = null;
#endif
/// <inheritdoc/>
protected override Size MeasureOverride(Size availableSize)
{
if (InternalChildren is null)
{
return new Size(0, 0);
}
double maxWidth = 0;
double maxHeight = 0;
for (var index = 0; index < InternalChildren.Count; index++)
{
var child = InternalChildren[index];
child?.Measure(availableSize);
if (child is null)
{
continue;
}
var childDesiredSize = child.DesiredSize;
maxWidth = Math.Max(maxWidth, childDesiredSize.Width);
maxHeight = Math.Max(maxHeight, childDesiredSize.Height);
}
// Panel size matches the largest child's size
return new Size((float)maxWidth, (float)maxHeight);
}
/// <inheritdoc/>
protected override Size ArrangeOverride(Size finalSize)
{
if (InternalChildren is null)
{
return finalSize;
}
// Arrange each child to occupy the same space (stacked on top of each other)
for (var index = 0; index < InternalChildren.Count; index++)
{
var child = InternalChildren[index];
// Positioning each child at (0, 0) ensures they are stacked on top of each other
child?.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
}
return finalSize;
}
private void OnLoaded(object sender, RoutedEventArgs args)
{
#if UNITY_5_3_OR_NEWER
// Cache children since calling Children in a loop seems to allocate
InternalChildren = Children.ToList();
#endif
Loaded -= OnLoaded;
}
}
Am I seeing these GetPropertyValue allocations because the structs get boxed? Can I avoid that somehow?
Also, I'm guessing feeding a Value Type into a IValueConverter will also always lead to boxing? For WPF it's fine but I'd love to avoid them in Unity if at all possible.
Also what's the Dictionary being used here?
Re: Help with avoiding memory allocations
We haven't forgotten about this post. However, the analysis requires time, and the team is quite busy preparing the first beta for Studio.
We will get back to this very soon.
We will get back to this very soon.
-
- KeldorKatarn
- Posts: 239
- Joined:
Re: Help with avoiding memory allocations
I found out by now that caching the children in OnLoaded caused a bug. But that's besides the point. I still couldn't tell where all those allocations came from. For now it's not a major issue I'm still in pre-production. But I'd like to hunt those down eventually.
Re: Help with avoiding memory allocations
Could you please create a ticket for this?
-
- KeldorKatarn
- Posts: 239
- Joined:
Re: Help with avoiding memory allocations
It's mainly this issue: https://www.noesisengine.com/bugs/view.php?id=3970Could you please create a ticket for this?
The boxing with value converters is a bit of a pain. There's no way to support generic Value converters I assume because that breaks compatibility with WPF?
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Help with avoiding memory allocations
What do you mean by generic value converters?
The Binding only allows to assign an IValueConverter, which has an API that works with object values for input and output. I don't think there is much we can do about it without breaking user code.
The Binding only allows to assign an IValueConverter, which has an API that works with object values for input and output. I don't think there is much we can do about it without breaking user code.
-
- KeldorKatarn
- Posts: 239
- Joined:
Re: Help with avoiding memory allocations
I'm aware. unfortunately one of the bad legacy design remnants of WPF before generics were widely used to avoid boxing.What do you mean by generic value converters?
The Binding only allows to assign an IValueConverter, which has an API that works with object values for input and output. I don't think there is much we can do about it without breaking user code.
I've since moved a lot of code that used value converters into specialized controls. Triggering value conversion every frame is isn't a good option.
Re: Help with avoiding memory allocations
Even with generics (which I’m not sure how they would be used in XAML), boxing is still needed, or at least, I don’t currently see a way to avoid it.
In C++, we pool boxed values, making the process quite fast without significant extra memory allocation. Shouldn't C# be doing something similar? Have you measured the cost of boxing on your platform?
In C++, we pool boxed values, making the process quite fast without significant extra memory allocation. Shouldn't C# be doing something similar? Have you measured the cost of boxing on your platform?
Who is online
Users browsing this forum: Ahrefs [Bot], Google [Bot], Semrush [Bot] and 3 guests