Skip to content

Commit 30fa159

Browse files
committed
perf(dp): Reduce property search allocations
1 parent 679bf73 commit 30fa159

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

src/Uno.UI/UI/Xaml/DependencyProperty.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ public sealed partial class DependencyProperty
3131
private readonly static TypeToPropertiesDictionary _getPropertiesForType = new TypeToPropertiesDictionary();
3232
private readonly static NameToPropertyDictionary _getPropertyCache = new NameToPropertyDictionary();
3333

34+
/// <summary>
35+
/// A static <see cref="PropertyCacheEntry"/> used for lookups and avoid creating new instances. This assumes that uses are non-reentrant.
36+
/// </summary>
37+
private readonly static PropertyCacheEntry _searchPropertyCacheEntry = new();
38+
39+
3440
private readonly static FrameworkPropertiesForTypeDictionary _getFrameworkPropertiesForType = new FrameworkPropertiesForTypeDictionary();
3541

3642
private readonly PropertyMetadata _ownerTypeMetadata; // For perf consideration, we keep direct ref the metadata for the owner type
@@ -317,12 +323,11 @@ internal bool IsUnoType
317323
/// <returns>A <see cref="DependencyProperty"/> instance, otherwise null it not found.</returns>
318324
internal static DependencyProperty GetProperty(Type type, string name)
319325
{
320-
DependencyProperty result = null;
321-
var key = new PropertyCacheEntry(type, name);
326+
_searchPropertyCacheEntry.Update(type, name);
322327

323-
if (!_getPropertyCache.TryGetValue(key, out result))
328+
if (!_getPropertyCache.TryGetValue(_searchPropertyCacheEntry, out var result))
324329
{
325-
_getPropertyCache.Add(key, result = InternalGetProperty(type, name));
330+
_getPropertyCache.Add(_searchPropertyCacheEntry.Clone(), result = InternalGetProperty(type, name));
326331
}
327332

328333
return result;
@@ -332,7 +337,9 @@ private static void ResetGetPropertyCache(Type ownerType, string name)
332337
{
333338
if (_getPropertyCache.Count != 0)
334339
{
335-
_getPropertyCache.Remove(new PropertyCacheEntry(ownerType, name));
340+
_searchPropertyCacheEntry.Update(ownerType, name);
341+
342+
_getPropertyCache.Remove(_searchPropertyCacheEntry);
336343
}
337344
}
338345

src/Uno.UI/UI/Xaml/DependencyPropertyCacheEntry.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using System;
44
using System.Collections;
5+
using System.Diagnostics.CodeAnalysis;
56
using System.Text;
67
using Uno.Core.Comparison;
78

@@ -12,11 +13,28 @@ namespace Windows.UI.Xaml
1213
/// </summary>
1314
internal class PropertyCacheEntry
1415
{
15-
private readonly Type Type;
16-
private readonly string Name;
17-
private readonly int CachedHashCode;
16+
private Type Type;
17+
private string Name;
18+
private int CachedHashCode;
1819

19-
public PropertyCacheEntry(Type type, string name)
20+
public PropertyCacheEntry()
21+
=> Update(typeof(object), "");
22+
23+
private PropertyCacheEntry(PropertyCacheEntry other)
24+
{
25+
CachedHashCode = other.CachedHashCode;
26+
Name = other.Name;
27+
Type = other.Type;
28+
}
29+
30+
public PropertyCacheEntry Clone()
31+
=> new(this);
32+
33+
/// <summary>
34+
/// Mutates the fields from this instance
35+
/// </summary>
36+
[MemberNotNull(nameof(Type), nameof(Name))]
37+
public void Update(Type type, string name)
2038
{
2139
this.Type = type;
2240
this.Name = name;

0 commit comments

Comments
 (0)