Remove allocations from lookahead

This makes lookahead allocation-free, saving about 15MB in our current
benchmark.
This commit is contained in:
Ryan Nowak 2016-01-14 16:15:27 -08:00
parent 7a0a9c6caa
commit ffdf5d2827
4 changed files with 14 additions and 18 deletions

View File

@ -5,14 +5,19 @@ using System;
namespace Microsoft.AspNet.Razor.Text namespace Microsoft.AspNet.Razor.Text
{ {
public class LookaheadToken : IDisposable public struct LookaheadToken : IDisposable
{ {
private Action _cancelAction; private readonly ITextBuffer _buffer;
private readonly int _position;
private bool _accepted; private bool _accepted;
public LookaheadToken(Action cancelAction) public LookaheadToken(ITextBuffer buffer)
{ {
_cancelAction = cancelAction; _buffer = buffer;
_position = buffer.Position;
_accepted = false;
} }
public void Accept() public void Accept()
@ -21,16 +26,10 @@ namespace Microsoft.AspNet.Razor.Text
} }
public void Dispose() public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{ {
if (!_accepted) if (!_accepted)
{ {
_cancelAction(); _buffer.Position = _position;
} }
} }
} }

View File

@ -25,10 +25,7 @@ namespace Microsoft.AspNet.Razor.Text
public static LookaheadToken BeginLookahead(this ITextBuffer self) public static LookaheadToken BeginLookahead(this ITextBuffer self)
{ {
var start = self.Position; var start = self.Position;
return new LookaheadToken(() => return new LookaheadToken(self);
{
self.Position = start;
});
} }
public static string ReadToEnd(this ITextBuffer self) public static string ReadToEnd(this ITextBuffer self)

View File

@ -165,7 +165,7 @@ namespace Microsoft.AspNet.Razor.Tokenizer
protected char Peek() protected char Peek()
{ {
using (LookaheadToken lookahead = Source.BeginLookahead()) using (var lookahead = Source.BeginLookahead())
{ {
MoveNext(); MoveNext();
return CurrentCharacter; return CurrentCharacter;
@ -250,7 +250,7 @@ namespace Microsoft.AspNet.Razor.Tokenizer
oldBuffer = Buffer.ToString(); oldBuffer = Buffer.ToString();
} }
using (LookaheadToken lookahead = Source.BeginLookahead()) using (var lookahead = Source.BeginLookahead())
{ {
for (int i = 0; i < expected.Length; i++) for (int i = 0; i < expected.Length; i++)
{ {

View File

@ -78,7 +78,7 @@ namespace Microsoft.AspNet.Razor.Test.Tokenizer
public void After_Accepting_Lookahead_Tokenizer_Returns_Next_Token() public void After_Accepting_Lookahead_Tokenizer_Returns_Next_Token()
{ {
var tokenizer = new HtmlTokenizer(new SeekableTextReader(new StringReader("<foo>"))); var tokenizer = new HtmlTokenizer(new SeekableTextReader(new StringReader("<foo>")));
using (LookaheadToken lookahead = tokenizer.Source.BeginLookahead()) using (var lookahead = tokenizer.Source.BeginLookahead())
{ {
Assert.Equal(new HtmlSymbol(0, 0, 0, "<", HtmlSymbolType.OpenAngle), tokenizer.NextSymbol()); Assert.Equal(new HtmlSymbol(0, 0, 0, "<", HtmlSymbolType.OpenAngle), tokenizer.NextSymbol());
Assert.Equal(new HtmlSymbol(1, 0, 1, "foo", HtmlSymbolType.Text), tokenizer.NextSymbol()); Assert.Equal(new HtmlSymbol(1, 0, 1, "foo", HtmlSymbolType.Text), tokenizer.NextSymbol());