Skip to content

Commit c27d0fc

Browse files
committed
Prevent unnecessary array allocations during validation
1 parent e0f70d2 commit c27d0fc

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

src/TurnerSoftware.RobotsExclusionTools/Tokenization/TokenPattern.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ namespace TurnerSoftware.RobotsExclusionTools.Tokenization
88
public class TokenPattern
99
{
1010
public TokenType Token { get; }
11-
public TokenType[] Preceeding { get; }
12-
public TokenType[] Succeeding { get; }
11+
public IReadOnlyCollection<TokenType> Preceeding { get; }
12+
public IReadOnlyCollection<TokenType> Succeeding { get; }
1313

1414
public TokenPattern(TokenType token, TokenType[] preceeding, TokenType[] succeeding)
1515
{
1616
Token = token;
17-
Preceeding = preceeding ?? new TokenType[0];
18-
Succeeding = succeeding ?? new TokenType[0];
17+
Preceeding = preceeding ?? Array.Empty<TokenType>();
18+
Succeeding = succeeding ?? Array.Empty<TokenType>();
1919
}
2020
}
2121
}

src/TurnerSoftware.RobotsExclusionTools/Tokenization/TokenPatternValidatorBase.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ private TokenValidationError ValidateToken(int lineNumber, TokenType tokenType,
6262

6363
private TokenValidationError ValidateTokenPattern(int lineNumber, TokenPattern tokenPattern, Stack<TokenType> preceeding, Queue<TokenType> succeeding)
6464
{
65-
if (tokenPattern.Preceeding.Length > 0)
65+
if (tokenPattern.Preceeding.Count > 0)
6666
{
6767
if (!PatternMatch(tokenPattern.Preceeding, preceeding))
6868
{
6969
return new TokenValidationError(lineNumber, $"Preceeding tokens did not match the pattern for token {tokenPattern.Token}", tokenPattern.Preceeding, preceeding);
7070
}
7171
}
7272

73-
if (tokenPattern.Succeeding.Length > 0)
73+
if (tokenPattern.Succeeding.Count > 0)
7474
{
7575
if (!PatternMatch(tokenPattern.Succeeding, succeeding))
7676
{
@@ -81,25 +81,32 @@ private TokenValidationError ValidateTokenPattern(int lineNumber, TokenPattern t
8181
return null;
8282
}
8383

84-
private bool PatternMatch(IEnumerable<TokenType> initialTokens, IEnumerable<TokenType> comparisonTokens)
84+
private bool PatternMatch(IReadOnlyCollection<TokenType> initialTokens, IReadOnlyCollection<TokenType> comparisonTokens)
8585
{
8686
//Check number of tokens match (though ignore required new lines)
8787
//This effectively allows "NewLine" tokens to be optional when there are no proceeding tokens (eg. at the start of the file)
88-
if (initialTokens.Count(t => t != TokenType.NewLine) > comparisonTokens.Count())
88+
if (initialTokens.Count(t => t != TokenType.NewLine) > comparisonTokens.Count)
8989
{
9090
return false;
9191
}
9292

93-
var sliceSize = Math.Min(initialTokens.Count(), comparisonTokens.Count());
94-
var slicedTokensArray = comparisonTokens.Take(sliceSize).ToArray();
93+
var index = 0;
94+
var length = Math.Min(initialTokens.Count, comparisonTokens.Count);
9595
var initialTokensArray = (TokenType[])initialTokens;
9696

97-
for (int i = 0, l = sliceSize; i < l; i++)
97+
foreach (var comparisonToken in comparisonTokens)
9898
{
99-
if (initialTokensArray[i] != slicedTokensArray[i])
99+
if (index >= length)
100+
{
101+
break;
102+
}
103+
104+
if (initialTokensArray[index] != comparisonToken)
100105
{
101106
return false;
102107
}
108+
109+
index++;
103110
}
104111

105112
return true;

0 commit comments

Comments
 (0)