Browse Source

Add a pooled option in BindingExpressionGrammar.

Micro-optimization.
pull/13970/head
Steven Kirk 3 years ago
parent
commit
d98c1f5ec4
  1. 7
      src/Markup/Avalonia.Markup/Data/Binding.cs
  2. 21
      src/Markup/Avalonia.Markup/Markup/Parsers/BindingExpressionGrammar.cs

7
src/Markup/Avalonia.Markup/Data/Binding.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Collections.Pooled;
using Avalonia.Controls;
using Avalonia.Data.Converters;
using Avalonia.Data.Core;
@ -104,7 +105,7 @@ namespace Avalonia.Data
if (!string.IsNullOrEmpty(Path))
{
var reader = new CharacterReader(Path.AsSpan());
var (astNodes, sourceMode) = BindingExpressionGrammar.Parse(ref reader);
var (astNodes, sourceMode) = BindingExpressionGrammar.ParseToPooledList(ref reader);
nodes = ExpressionNodeFactory.CreateFromAst(
astNodes,
TypeResolver,
@ -137,9 +138,9 @@ namespace Avalonia.Data
if (!string.IsNullOrEmpty(Path))
{
var reader = new CharacterReader(Path.AsSpan());
var (astNodes, sourceMode) = BindingExpressionGrammar.Parse(ref reader);
var (astPool, sourceMode) = BindingExpressionGrammar.ParseToPooledList(ref reader);
nodes = ExpressionNodeFactory.CreateFromAst(
astNodes,
astPool,
TypeResolver,
GetNameScope(),
out isRooted);

21
src/Markup/Avalonia.Markup/Markup/Parsers/BindingExpressionGrammar.cs

@ -16,9 +16,26 @@ namespace Avalonia.Markup.Parsers
internal static class BindingExpressionGrammar
{
private static readonly List<INode> s_pool = new();
public static (List<INode> Nodes, SourceMode Mode) Parse(ref CharacterReader r)
{
var nodes = new List<INode>();
var result = new List<INode>();
var mode = Parse(ref r, result);
return (result, mode);
}
public static (List<INode> Nodes, SourceMode Mode) ParseToPooledList(ref CharacterReader r)
{
// Most of the time the list will be passed to `ExpressionNodeFactory.CreateFromAst`
// and then discarded so as a micro-optimization we can reuse the list.
s_pool.Clear();
var mode = Parse(ref r, s_pool);
return (s_pool, mode);
}
private static SourceMode Parse(ref CharacterReader r, List<INode> nodes)
{
var state = State.Start;
var mode = SourceMode.Data;
@ -72,7 +89,7 @@ namespace Avalonia.Markup.Parsers
throw new ExpressionParseException(r.Position, "Unexpected end of expression.");
}
return (nodes, mode);
return mode;
}
private static State ParseStart(ref CharacterReader r, IList<INode> nodes)

Loading…
Cancel
Save