Optimize allocations of List<ISymbol> and related
This commit is contained in:
parent
ffdf5d2827
commit
95ea4cc06f
|
|
@ -16,6 +16,7 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
|
||||||
public class Span : SyntaxTreeNode
|
public class Span : SyntaxTreeNode
|
||||||
{
|
{
|
||||||
private static readonly int TypeHashCode = typeof(Span).GetHashCode();
|
private static readonly int TypeHashCode = typeof(Span).GetHashCode();
|
||||||
|
private string _content;
|
||||||
private SourceLocation _start;
|
private SourceLocation _start;
|
||||||
|
|
||||||
public Span(SpanBuilder builder)
|
public Span(SpanBuilder builder)
|
||||||
|
|
@ -24,7 +25,7 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpanKind Kind { get; protected set; }
|
public SpanKind Kind { get; protected set; }
|
||||||
public IEnumerable<ISymbol> Symbols { get; protected set; }
|
public IReadOnlyList<ISymbol> Symbols { get; protected set; }
|
||||||
|
|
||||||
// Allow test code to re-link spans
|
// Allow test code to re-link spans
|
||||||
public Span Previous { get; protected internal set; }
|
public Span Previous { get; protected internal set; }
|
||||||
|
|
@ -48,7 +49,25 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
|
||||||
get { return _start; }
|
get { return _start; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Content { get; private set; }
|
public string Content
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_content == null)
|
||||||
|
{
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
for (var i = 0; i < Symbols.Count; i++)
|
||||||
|
{
|
||||||
|
var symbol = Symbols[i];
|
||||||
|
builder.Append(symbol.Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
_content = builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Change(Action<SpanBuilder> changes)
|
public void Change(Action<SpanBuilder> changes)
|
||||||
{
|
{
|
||||||
|
|
@ -59,19 +78,15 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
|
||||||
|
|
||||||
public void ReplaceWith(SpanBuilder builder)
|
public void ReplaceWith(SpanBuilder builder)
|
||||||
{
|
{
|
||||||
Debug.Assert(!builder.Symbols.Any() || builder.Symbols.All(s => s != null));
|
|
||||||
|
|
||||||
Kind = builder.Kind;
|
Kind = builder.Kind;
|
||||||
Symbols = builder.Symbols;
|
Symbols = builder.Symbols;
|
||||||
EditHandler = builder.EditHandler;
|
EditHandler = builder.EditHandler;
|
||||||
ChunkGenerator = builder.ChunkGenerator ?? SpanChunkGenerator.Null;
|
ChunkGenerator = builder.ChunkGenerator ?? SpanChunkGenerator.Null;
|
||||||
_start = builder.Start;
|
_start = builder.Start;
|
||||||
|
_content = null;
|
||||||
|
|
||||||
// Since we took references to the values in SpanBuilder, clear its references out
|
// Since we took references to the values in SpanBuilder, clear its references out
|
||||||
builder.Reset();
|
builder.Reset();
|
||||||
|
|
||||||
// Calculate other properties
|
|
||||||
Content = Symbols.Aggregate(new StringBuilder(), (sb, sym) => sb.Append(sym.Content), sb => sb.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNet.Razor.Editor;
|
using Microsoft.AspNet.Razor.Editor;
|
||||||
using Microsoft.AspNet.Razor.Chunks.Generators;
|
using Microsoft.AspNet.Razor.Chunks.Generators;
|
||||||
|
|
@ -13,7 +12,7 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
|
||||||
{
|
{
|
||||||
public class SpanBuilder
|
public class SpanBuilder
|
||||||
{
|
{
|
||||||
private IList<ISymbol> _symbols = new List<ISymbol>();
|
private List<ISymbol> _symbols;
|
||||||
private SourceLocationTracker _tracker = new SourceLocationTracker();
|
private SourceLocationTracker _tracker = new SourceLocationTracker();
|
||||||
|
|
||||||
public SpanBuilder(Span original)
|
public SpanBuilder(Span original)
|
||||||
|
|
@ -31,11 +30,20 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceLocation Start { get; set; }
|
public SourceLocation Start { get; set; }
|
||||||
|
|
||||||
public SpanKind Kind { get; set; }
|
public SpanKind Kind { get; set; }
|
||||||
|
|
||||||
public ReadOnlyCollection<ISymbol> Symbols
|
public IReadOnlyList<ISymbol> Symbols
|
||||||
{
|
{
|
||||||
get { return new ReadOnlyCollection<ISymbol>(_symbols); }
|
get
|
||||||
|
{
|
||||||
|
if (_symbols == null)
|
||||||
|
{
|
||||||
|
_symbols = new List<ISymbol>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _symbols;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpanEditHandler EditHandler { get; set; }
|
public SpanEditHandler EditHandler { get; set; }
|
||||||
|
|
@ -43,7 +51,10 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
_symbols = new List<ISymbol>();
|
// Need to potentially allocate a new list because Span.ReplaceWith takes ownership
|
||||||
|
// of the original list.
|
||||||
|
_symbols = null;
|
||||||
|
|
||||||
EditHandler = SpanEditHandler.CreateDefault(s => Enumerable.Empty<ISymbol>());
|
EditHandler = SpanEditHandler.CreateDefault(s => Enumerable.Empty<ISymbol>());
|
||||||
ChunkGenerator = SpanChunkGenerator.Null;
|
ChunkGenerator = SpanChunkGenerator.Null;
|
||||||
Start = SourceLocation.Zero;
|
Start = SourceLocation.Zero;
|
||||||
|
|
@ -67,6 +78,11 @@ namespace Microsoft.AspNet.Razor.Parser.SyntaxTree
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_symbols == null)
|
||||||
|
{
|
||||||
|
_symbols = new List<ISymbol>();
|
||||||
|
}
|
||||||
|
|
||||||
if (_symbols.Count == 0)
|
if (_symbols.Count == 0)
|
||||||
{
|
{
|
||||||
Start = symbol.Start;
|
Start = symbol.Start;
|
||||||
|
|
|
||||||
|
|
@ -647,8 +647,9 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
EnsureTagBlock(tagBlock);
|
EnsureTagBlock(tagBlock);
|
||||||
|
|
||||||
var childSpan = (Span)tagBlock.Children.First();
|
var childSpan = (Span)tagBlock.Children.First();
|
||||||
|
|
||||||
// We grab the symbol that could be forward slash
|
// We grab the symbol that could be forward slash
|
||||||
var relevantSymbol = (HtmlSymbol)childSpan.Symbols.Take(2).Last();
|
var relevantSymbol = (HtmlSymbol)childSpan.Symbols[childSpan.Symbols.Count == 1 ? 0 : 1];
|
||||||
|
|
||||||
return relevantSymbol.Type == HtmlSymbolType.ForwardSlash;
|
return relevantSymbol.Type == HtmlSymbolType.ForwardSlash;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue