Skip to content

Commit 76a67c5

Browse files
committed
Reduced memory usage in UniformGrid.MeasureOverride
1 parent c521c21 commit 76a67c5

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

Microsoft.Toolkit.Uwp.UI.Controls/UniformGrid/TakenSpotsReferenceHolder.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
1313
/// <see cref="UniformGrid.GetFreeSpot"/> iterator.
1414
/// This is used so we can better isolate our logic and make it easier to test.
1515
/// </summary>
16-
internal class TakenSpotsReferenceHolder
16+
internal sealed class TakenSpotsReferenceHolder
1717
{
1818
/// <summary>
1919
/// The <see cref="BitArray"/> instance used to efficiently track empty spots.
@@ -53,8 +53,16 @@ public TakenSpotsReferenceHolder(int rows, int columns)
5353
/// <param name="j">The horizontal offset.</param>
5454
public bool this[int i, int j]
5555
{
56-
get => spotsTaken[(i * Width) + j];
57-
set => spotsTaken[(i * Width) + j] = value;
56+
get => this.spotsTaken[(i * Width) + j];
57+
set => this.spotsTaken[(i * Width) + j] = value;
58+
}
59+
60+
/// <summary>
61+
/// Resets the current reference holder.
62+
/// </summary>
63+
public void Reset()
64+
{
65+
this.spotsTaken.SetAll(false);
5866
}
5967
}
6068
}

Microsoft.Toolkit.Uwp.UI.Controls/UniformGrid/UniformGrid.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public partial class UniformGrid : Grid
2323
// Internal list we use to keep track of items that we don't have space to layout.
2424
private List<UIElement> _overflow = new List<UIElement>();
2525

26+
/// <summary>
27+
/// The <see cref="TakenSpotsReferenceHolder"/> instance in use, if any.
28+
/// </summary>
29+
private TakenSpotsReferenceHolder _spotref;
30+
2631
/// <inheritdoc/>
2732
protected override Size MeasureOverride(Size availableSize)
2833
{
@@ -39,7 +44,20 @@ protected override Size MeasureOverride(Size availableSize)
3944
SetupRowDefinitions(rows);
4045
SetupColumnDefinitions(columns);
4146

42-
var spotref = new TakenSpotsReferenceHolder(rows, columns);
47+
TakenSpotsReferenceHolder spotref;
48+
49+
// If the last spot holder matches the size currently in use, just reset
50+
// that instance and reuse it to avoid allocating a new bit array.
51+
if (_spotref != null && _spotref.Height == rows && _spotref.Width == columns)
52+
{
53+
spotref = _spotref;
54+
55+
spotref.Reset();
56+
}
57+
else
58+
{
59+
spotref = _spotref = new TakenSpotsReferenceHolder(rows, columns);
60+
}
4361

4462
// Figure out which children we should automatically layout and where available openings are.
4563
foreach (var child in visible)

0 commit comments

Comments
 (0)