Skip to content

Commit

Permalink
perf: Add a fast path for GetValue
Browse files Browse the repository at this point in the history
  • Loading branch information
Youssef1313 committed Sep 27, 2023
1 parent 236445f commit 0112ea9
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
31 changes: 31 additions & 0 deletions src/Uno.UI/UI/Xaml/DependencyObjectStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,37 @@ private void Dispose(bool disposing)

ValidatePropertyOwner(property);

// As a performance optimization, avoid creating the property details and try get the value in this fast path.
if ((propertyDetails ??= _properties.FindPropertyDetails(property)) is null)
{
// Since property details wasn't created, the only possibilities are returning UnsetValue or the default value.
// UnsetValue is returned when we are asked for a non-DefaultValue precedence specific value.
// Otherwise, we calculate the default value, first by calling `GetDefaultValue2`, then from property metadata.
if (isPrecedenceSpecific)
{
Debug.Assert(precedence is not null);
if (precedence != DependencyPropertyValuePrecedences.DefaultValue)
{
return UnsetValue.Instance;
}
}

if (ActualInstance is UIElement uiElement && uiElement.GetDefaultValue2(property, out var defaultValue))
{
return defaultValue;
}

defaultValue = property.GetMetadata(_originalObjectType).DefaultValue;

// Ensures that the default value of non-nullable properties is not null
if (defaultValue == null && !property.IsTypeNullable)
{
defaultValue = property.GetFallbackDefaultValue();
}

return defaultValue;
}

propertyDetails ??= _properties.GetPropertyDetails(property);

return GetValue(propertyDetails, precedence, isPrecedenceSpecific);
Expand Down
20 changes: 13 additions & 7 deletions src/Uno.UI/UI/Xaml/DependencyPropertyDetailsCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,19 +131,19 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property
// https://stackoverflow.com/a/17095534/26346
var isInRange = (uint)entryIndex <= (_maxId - _minId);

GetPropertyInheritanceConfiguration(
property: property,
hasInherits: out var hasInherits,
hasValueInherits: out var hasValueInherits,
hasValueDoesNotInherit: out var hasValueDoesNotInherits
);

if (isInRange)
{
ref var propertyEntry = ref Entries![entryIndex];

if (forceCreate && propertyEntry == null)
{
GetPropertyInheritanceConfiguration(
property: property,
hasInherits: out var hasInherits,
hasValueInherits: out var hasValueInherits,
hasValueDoesNotInherit: out var hasValueDoesNotInherits
);

propertyEntry = new DependencyPropertyDetails(property, _ownerType, hasInherits, hasValueInherits, hasValueDoesNotInherits);

if (TryResolveDefaultValueFromProviders(property, out var value))
Expand Down Expand Up @@ -182,6 +182,12 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property
}

ref var propertyEntry = ref Entries![property.UniqueId - _minId];
GetPropertyInheritanceConfiguration(
property: property,
hasInherits: out var hasInherits,
hasValueInherits: out var hasValueInherits,
hasValueDoesNotInherit: out var hasValueDoesNotInherits
);
propertyEntry = new DependencyPropertyDetails(property, _ownerType, hasInherits, hasValueInherits, hasValueDoesNotInherits);
if (TryResolveDefaultValueFromProviders(property, out var value))
{
Expand Down

0 comments on commit 0112ea9

Please sign in to comment.