Skip to content

Commit

Permalink
perf: Improve nullability checking in DependencyProperty
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jeromelaban committed Sep 7, 2021
1 parent fbf79fb commit 5f50f1f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#nullable enable

using System;
using Uno.Collections;
using Uno.UI.Helpers;
using Uno.Extensions;

namespace Windows.UI.Xaml
{
public sealed partial class DependencyProperty
{
private readonly static TypeNullableDictionary _isTypeNullableDictionary = new TypeNullableDictionary();

private bool GetIsTypeNullable(Type type)
{
if(!_isTypeNullableDictionary.TryGetValue(type, out var isNullable))
{
_isTypeNullableDictionary.Add(type, isNullable = type.IsNullable());
}

return isNullable;
}

private class TypeNullableDictionary
{
private readonly HashtableEx _entries = new HashtableEx(FastTypeComparer.Default);

internal bool TryGetValue(Type key, out bool result)
{
if (_entries.TryGetValue(key, out var value))
{
result = (bool)value!;
return true;
}

result = false;
return false;
}

internal void Add(Type key, bool isNullable)
=> _entries.Add(key, isNullable);

internal void Clear()
=> _entries.Clear();
}
}
}
2 changes: 1 addition & 1 deletion src/Uno.UI/UI/Xaml/DependencyProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private DependencyProperty(string name, Type propertyType, Type ownerType, Prope
_ownerType = ownerType;
_isAttached = attached;
_isDependencyObjectCollection = typeof(DependencyObjectCollection).IsAssignableFrom(propertyType);
_isTypeNullable = propertyType.IsNullableCached();
_isTypeNullable = GetIsTypeNullable(propertyType);
_uniqueId = Interlocked.Increment(ref _globalId);
_hasWeakStorage = (defaultMetadata as FrameworkPropertyMetadata)?.Options.HasWeakStorage() ?? false;

Expand Down

0 comments on commit 5f50f1f

Please sign in to comment.