Skip to content

Commit 5f50f1f

Browse files
committed
perf: Improve nullability checking in DependencyProperty
Move nullability checking to use `HashTableEx` to avoid JIT/Generics costs when initializing DependencyProperty nullability validation. The original implementation is in Uno.Core, but uses ConcurrentDictionary, which is particularly expensive to initialize in Jitted and Full AOT environments.
1 parent fbf79fb commit 5f50f1f

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#nullable enable
2+
3+
using System;
4+
using Uno.Collections;
5+
using Uno.UI.Helpers;
6+
using Uno.Extensions;
7+
8+
namespace Windows.UI.Xaml
9+
{
10+
public sealed partial class DependencyProperty
11+
{
12+
private readonly static TypeNullableDictionary _isTypeNullableDictionary = new TypeNullableDictionary();
13+
14+
private bool GetIsTypeNullable(Type type)
15+
{
16+
if(!_isTypeNullableDictionary.TryGetValue(type, out var isNullable))
17+
{
18+
_isTypeNullableDictionary.Add(type, isNullable = type.IsNullable());
19+
}
20+
21+
return isNullable;
22+
}
23+
24+
private class TypeNullableDictionary
25+
{
26+
private readonly HashtableEx _entries = new HashtableEx(FastTypeComparer.Default);
27+
28+
internal bool TryGetValue(Type key, out bool result)
29+
{
30+
if (_entries.TryGetValue(key, out var value))
31+
{
32+
result = (bool)value!;
33+
return true;
34+
}
35+
36+
result = false;
37+
return false;
38+
}
39+
40+
internal void Add(Type key, bool isNullable)
41+
=> _entries.Add(key, isNullable);
42+
43+
internal void Clear()
44+
=> _entries.Clear();
45+
}
46+
}
47+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private DependencyProperty(string name, Type propertyType, Type ownerType, Prope
5555
_ownerType = ownerType;
5656
_isAttached = attached;
5757
_isDependencyObjectCollection = typeof(DependencyObjectCollection).IsAssignableFrom(propertyType);
58-
_isTypeNullable = propertyType.IsNullableCached();
58+
_isTypeNullable = GetIsTypeNullable(propertyType);
5959
_uniqueId = Interlocked.Increment(ref _globalId);
6060
_hasWeakStorage = (defaultMetadata as FrameworkPropertyMetadata)?.Options.HasWeakStorage() ?? false;
6161

0 commit comments

Comments
 (0)