Refactor RenderTreeDiffComputer to use more "ref local" for less array dereferencing

This commit is contained in:
Steve Sanderson 2018-01-29 11:59:44 +00:00
parent 772e3a1a44
commit 7e76490844
1 changed files with 37 additions and 36 deletions

View File

@ -52,8 +52,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
if (oldSeq == newSeq) if (oldSeq == newSeq)
{ {
AppendDiffEntriesForNodesWithSameSequence(oldTree, oldStartIndex, newTree, newStartIndex, ref siblingIndex); AppendDiffEntriesForNodesWithSameSequence(oldTree, oldStartIndex, newTree, newStartIndex, ref siblingIndex);
oldStartIndex = NextSiblingIndex(oldTree, oldStartIndex); oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex);
newStartIndex = NextSiblingIndex(newTree, newStartIndex); newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex);
hasMoreOld = oldEndIndexExcl > oldStartIndex; hasMoreOld = oldEndIndexExcl > oldStartIndex;
hasMoreNew = newEndIndexExcl > newStartIndex; hasMoreNew = newEndIndexExcl > newStartIndex;
prevOldSeq = oldSeq; prevOldSeq = oldSeq;
@ -126,7 +126,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
if (treatAsInsert) if (treatAsInsert)
{ {
var newNodeType = newTree[newStartIndex].NodeType; ref var newNode = ref newTree[newStartIndex];
var newNodeType = newNode.NodeType;
if (newNodeType == RenderTreeNodeType.Attribute) if (newNodeType == RenderTreeNodeType.Attribute)
{ {
Append(RenderTreeEdit.SetAttribute(siblingIndex, newStartIndex)); Append(RenderTreeEdit.SetAttribute(siblingIndex, newStartIndex));
@ -140,7 +141,7 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
} }
Append(RenderTreeEdit.PrependNode(siblingIndex, newStartIndex)); Append(RenderTreeEdit.PrependNode(siblingIndex, newStartIndex));
newStartIndex = NextSiblingIndex(newTree, newStartIndex); newStartIndex = NextSiblingIndex(newNode, newStartIndex);
siblingIndex++; siblingIndex++;
} }
@ -149,15 +150,16 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
} }
else else
{ {
if (oldTree[oldStartIndex].NodeType == RenderTreeNodeType.Attribute) ref var oldNode = ref oldTree[oldStartIndex];
if (oldNode.NodeType == RenderTreeNodeType.Attribute)
{ {
Append(RenderTreeEdit.RemoveAttribute(siblingIndex, oldTree[oldStartIndex].AttributeName)); Append(RenderTreeEdit.RemoveAttribute(siblingIndex, oldNode.AttributeName));
oldStartIndex++; oldStartIndex++;
} }
else else
{ {
Append(RenderTreeEdit.RemoveNode(siblingIndex)); Append(RenderTreeEdit.RemoveNode(siblingIndex));
oldStartIndex = NextSiblingIndex(oldTree, oldStartIndex); oldStartIndex = NextSiblingIndex(oldNode, oldStartIndex);
} }
hasMoreOld = oldEndIndexExcl > oldStartIndex; hasMoreOld = oldEndIndexExcl > oldStartIndex;
prevOldSeq = oldSeq; prevOldSeq = oldSeq;
@ -198,13 +200,15 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
if (oldSeq == newSeq) if (oldSeq == newSeq)
{ {
var oldName = oldTree[oldStartIndex].AttributeName; ref var oldNode = ref oldTree[oldStartIndex];
var newName = newTree[newStartIndex].AttributeName; ref var newNode = ref newTree[newStartIndex];
var newPropertyValue = newTree[newStartIndex].AttributeValue; var oldName = oldNode.AttributeName;
var newName = newNode.AttributeName;
var newPropertyValue = newNode.AttributeValue;
if (string.Equals(oldName, newName, StringComparison.Ordinal)) if (string.Equals(oldName, newName, StringComparison.Ordinal))
{ {
// Using Equals to account for string comparisons, nulls, etc. // Using Equals to account for string comparisons, nulls, etc.
var oldPropertyValue = oldTree[oldStartIndex].AttributeValue; var oldPropertyValue = oldNode.AttributeValue;
if (!Equals(oldPropertyValue, newPropertyValue)) if (!Equals(oldPropertyValue, newPropertyValue))
{ {
SetChildComponentProperty(componentInstance, newName, newPropertyValue); SetChildComponentProperty(componentInstance, newName, newPropertyValue);
@ -235,17 +239,16 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
if (treatAsInsert) if (treatAsInsert)
{ {
SetChildComponentProperty(componentInstance, ref var newNode = ref newTree[newStartIndex];
newTree[newStartIndex].AttributeName, SetChildComponentProperty(componentInstance, newNode.AttributeName, newNode.AttributeValue);
newTree[newStartIndex].AttributeValue);
hasSetAnyProperty = true; hasSetAnyProperty = true;
newStartIndex++; newStartIndex++;
hasMoreNew = newEndIndexIncl >= newStartIndex; hasMoreNew = newEndIndexIncl >= newStartIndex;
} }
else else
{ {
RemoveChildComponentProperty(componentInstance, ref var oldNode = ref oldTree[oldStartIndex];
oldTree[oldStartIndex].AttributeName); RemoveChildComponentProperty(componentInstance, oldNode.AttributeName);
hasSetAnyProperty = true; hasSetAnyProperty = true;
oldStartIndex++; oldStartIndex++;
hasMoreOld = oldEndIndexIncl >= oldStartIndex; hasMoreOld = oldEndIndexIncl >= oldStartIndex;
@ -298,9 +301,9 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
return property; return property;
} }
private static int NextSiblingIndex(RenderTreeNode[] tree, int nodeIndex) private static int NextSiblingIndex(in RenderTreeNode node, int nodeIndex)
{ {
var descendantsEndIndex = tree[nodeIndex].ElementDescendantsEndIndex; var descendantsEndIndex = node.ElementDescendantsEndIndex;
return (descendantsEndIndex == 0 ? nodeIndex : descendantsEndIndex) + 1; return (descendantsEndIndex == 0 ? nodeIndex : descendantsEndIndex) + 1;
} }
@ -309,8 +312,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
RenderTreeNode[] newTree, int newNodeIndex, RenderTreeNode[] newTree, int newNodeIndex,
ref int siblingIndex) ref int siblingIndex)
{ {
// TODO: Refactor to use a "ref var oldNode/newNode" everywhere in this method ref var oldNode = ref oldTree[oldNodeIndex];
// Same in other methods in this class that do a lot of indexing into RenderTreeNode[] ref var newNode = ref newTree[newNodeIndex];
// We can assume that the old and new nodes are of the same type, because they correspond // We can assume that the old and new nodes are of the same type, because they correspond
// to the same sequence number (and if not, the behaviour is undefined). // to the same sequence number (and if not, the behaviour is undefined).
@ -318,8 +321,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
{ {
case RenderTreeNodeType.Text: case RenderTreeNodeType.Text:
{ {
var oldText = oldTree[oldNodeIndex].TextContent; var oldText = oldNode.TextContent;
var newText = newTree[newNodeIndex].TextContent; var newText = newNode.TextContent;
if (!string.Equals(oldText, newText, StringComparison.Ordinal)) if (!string.Equals(oldText, newText, StringComparison.Ordinal))
{ {
Append(RenderTreeEdit.UpdateText(siblingIndex, newNodeIndex)); Append(RenderTreeEdit.UpdateText(siblingIndex, newNodeIndex));
@ -330,8 +333,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
case RenderTreeNodeType.Element: case RenderTreeNodeType.Element:
{ {
var oldElementName = oldTree[oldNodeIndex].ElementName; var oldElementName = oldNode.ElementName;
var newElementName = newTree[newNodeIndex].ElementName; var newElementName = newNode.ElementName;
if (string.Equals(oldElementName, newElementName, StringComparison.Ordinal)) if (string.Equals(oldElementName, newElementName, StringComparison.Ordinal))
{ {
var oldNodeAttributesEndIndexExcl = GetAttributesEndIndexExclusive(oldTree, oldNodeIndex); var oldNodeAttributesEndIndexExcl = GetAttributesEndIndexExclusive(oldTree, oldNodeIndex);
@ -344,8 +347,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
ref siblingIndex); ref siblingIndex);
// Diff the children // Diff the children
var oldNodeChildrenEndIndexExcl = oldTree[oldNodeIndex].ElementDescendantsEndIndex + 1; var oldNodeChildrenEndIndexExcl = oldNode.ElementDescendantsEndIndex + 1;
var newNodeChildrenEndIndexExcl = newTree[newNodeIndex].ElementDescendantsEndIndex + 1; var newNodeChildrenEndIndexExcl = newNode.ElementDescendantsEndIndex + 1;
var hasChildrenToProcess = var hasChildrenToProcess =
oldNodeChildrenEndIndexExcl > oldNodeAttributesEndIndexExcl || oldNodeChildrenEndIndexExcl > oldNodeAttributesEndIndexExcl ||
newNodeChildrenEndIndexExcl > newNodeAttributesEndIndexExcl; newNodeChildrenEndIndexExcl > newNodeAttributesEndIndexExcl;
@ -377,8 +380,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
case RenderTreeNodeType.Component: case RenderTreeNodeType.Component:
{ {
var oldComponentType = oldTree[oldNodeIndex].ComponentType; var oldComponentType = oldNode.ComponentType;
var newComponentType = newTree[newNodeIndex].ComponentType; var newComponentType = newNode.ComponentType;
if (oldComponentType == newComponentType) if (oldComponentType == newComponentType)
{ {
UpdateRetainedChildComponent( UpdateRetainedChildComponent(
@ -399,14 +402,12 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
case RenderTreeNodeType.Attribute: case RenderTreeNodeType.Attribute:
{ {
var oldName = oldTree[oldNodeIndex].AttributeName; var oldName = oldNode.AttributeName;
var newName = newTree[newNodeIndex].AttributeName; var newName = newNode.AttributeName;
if (string.Equals(oldName, newName, StringComparison.Ordinal)) if (string.Equals(oldName, newName, StringComparison.Ordinal))
{ {
// Using Equals to account for string comparisons, nulls, etc. // Using Equals to account for string comparisons, nulls, etc.
var valueChanged = !Equals( var valueChanged = !Equals(oldNode.AttributeValue, newNode.AttributeValue);
oldTree[oldNodeIndex].AttributeValue,
newTree[newNodeIndex].AttributeValue);
if (valueChanged) if (valueChanged)
{ {
Append(RenderTreeEdit.SetAttribute(siblingIndex, newNodeIndex)); Append(RenderTreeEdit.SetAttribute(siblingIndex, newNodeIndex));
@ -459,10 +460,10 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
_entries.Append(entry); _entries.Append(entry);
} }
private void InstantiateChildComponents(RenderTreeNode[] nodes, int startIndex) private void InstantiateChildComponents(RenderTreeNode[] nodes, int elementOrComponentIndex)
{ {
var endIndex = nodes[startIndex].ElementDescendantsEndIndex; var endIndex = nodes[elementOrComponentIndex].ElementDescendantsEndIndex;
for (var i = startIndex; i <= endIndex; i++) for (var i = elementOrComponentIndex; i <= endIndex; i++)
{ {
if (nodes[i].NodeType == RenderTreeNodeType.Component) if (nodes[i].NodeType == RenderTreeNodeType.Component)
{ {