Skip to content

Commit 23f0c0b

Browse files
jensjohaCommit Queue
authored andcommitted
[scanner/paser] Don't use identical on ints
Short explanation: For whatever reason, when using `identical` on `int`s the ints are first boxed (`BoxInt64`) before being compared (`StrictCompare`) whereas just doing `==` just does a compare (`EqualityCompare`). Results: With the CFE compiling (a fixed version of) itself I get these results: ``` instructions:u: -0.5756% +/- 0.0003% (-124825401.80 +/- 64013.17) ``` i.e. almost 125 mio instructions saved. Another run - with 100 iterations each - I get ``` msec task-clock:u: -0.4927% +/- 0.2585% (-20.85 +/- 10.94) page-faults:u: 0.0174% +/- 0.0139% (18.80 +/- 15.00) cycles:u: -0.5233% +/- 0.2683% (-91305451.82 +/- 46815747.30) instructions:u: -0.5754% +/- 0.0002% (-124793061.49 +/- 37426.30) branch-misses:u: -1.6903% +/- 1.1207% (-1091410.69 +/- 723627.04) seconds time elapsed: -0.4863% +/- 0.2581% (-0.02 +/- 0.01) seconds user: -0.4547% +/- 0.3253% (-0.02 +/- 0.01) ``` In the scanner benchmark with `--string` (i.e. using string scanner) I get these results: ``` msec task-clock:u: -3.7992% +/- 0.3316% (-190.54 +/- 16.63) cycles:u: -4.1423% +/- 0.3566% (-836808313.28 +/- 72033424.19) instructions:u: -3.3524% +/- 0.0000% (-1480262370.08 +/- 828.58) branch-misses:u: -1.7591% +/- 0.9582% (-1781144.28 +/- 970258.82) seconds time elapsed: -3.7988% +/- 0.3303% (-0.19 +/- 0.02) seconds user: -4.0211% +/- 0.4161% (-0.19 +/- 0.02) ``` (Just running the benchmark also sees the characters/µs go from ~93 to ~97). In the scanner benchmark with `--bytes` (i.e. using the utf8 scanner) I get these results: ``` msec task-clock:u: -4.2872% +/- 0.4467% (-185.64 +/- 19.34) cycles:u: -4.2972% +/- 0.4382% (-812955454.92 +/- 82892232.23) instructions:u: -3.4867% +/- 0.0000% (-1479744935.28 +/- 297.12) seconds time elapsed: -4.2872% +/- 0.4470% (-0.19 +/- 0.02) seconds user: -4.2204% +/- 0.4730% (-0.18 +/- 0.02) ``` (Just running the benchmark also sees the bytes/µs go from ~108 to ~113). In both cases we notice how the actual time, cycles and instructions agree pretty well. Combining the data for the compile and the benchmark I assume this CL actually reduces the runtime of the CFE compiling itself by a about half a percent. Change-Id: I67d056837240aef61b6707d02507ab4121b31715 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385940 Commit-Queue: Jens Johansen <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 465bbbd commit 23f0c0b

File tree

6 files changed

+224
-194
lines changed

6 files changed

+224
-194
lines changed

pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,8 +3356,7 @@ class Parser {
33563356
}
33573357

33583358
bool notEofOrValue(String value, Token token) {
3359-
return !identical(token.kind, EOF_TOKEN) &&
3360-
!identical(value, token.stringValue);
3359+
return token.kind != EOF_TOKEN && value != token.stringValue;
33613360
}
33623361

33633362
Token parseTypeVariablesOpt(Token token) {
@@ -4279,7 +4278,7 @@ class Parser {
42794278
/// Call `parseLiteralString` and return the result.
42804279
Token ensureLiteralString(Token token) {
42814280
Token next = token.next!;
4282-
if (!identical(next.kind, STRING_TOKEN)) {
4281+
if (next.kind != STRING_TOKEN) {
42834282
codes.Message message = codes.templateExpectedString.withArguments(next);
42844283
Token newToken = new SyntheticStringToken(
42854284
TokenType.STRING, '""', next.charOffset, /* _length = */ 0);
@@ -4832,8 +4831,8 @@ class Parser {
48324831
if (getOrSet == null && optional('operator', name)) {
48334832
Token operator = name.next!;
48344833
if (operator.isOperator ||
4835-
identical(operator.kind, EQ_EQ_EQ_TOKEN) ||
4836-
identical(operator.kind, BANG_EQ_EQ_TOKEN) ||
4834+
operator.kind == EQ_EQ_EQ_TOKEN ||
4835+
operator.kind == BANG_EQ_EQ_TOKEN ||
48374836
isUnaryMinus(operator)) {
48384837
isOperator = true;
48394838
if (optional(">>", operator) &&
@@ -5588,7 +5587,7 @@ class Parser {
55885587
}
55895588

55905589
Token parseStatementX(Token token) {
5591-
if (identical(token.next!.kind, IDENTIFIER_TOKEN)) {
5590+
if (token.next!.kind == IDENTIFIER_TOKEN) {
55925591
if (optional(':', token.next!.next!)) {
55935592
return parseLabeledStatement(token);
55945593
}
@@ -5974,10 +5973,10 @@ class Parser {
59745973
for (int level = tokenLevel; level >= precedence; --level) {
59755974
int lastBinaryExpressionLevel = -1;
59765975
Token? lastCascade;
5977-
while (identical(tokenLevel, level)) {
5976+
while (tokenLevel == level) {
59785977
enteredLoop = true;
59795978
Token operator = next;
5980-
if (identical(tokenLevel, CASCADE_PRECEDENCE)) {
5979+
if (tokenLevel == CASCADE_PRECEDENCE) {
59815980
if (!allowCascades) {
59825981
return token;
59835982
} else if (lastCascade != null && optional('?..', next)) {
@@ -5986,7 +5985,7 @@ class Parser {
59865985
}
59875986
lastCascade = next;
59885987
token = parseCascadeExpression(token);
5989-
} else if (identical(tokenLevel, ASSIGNMENT_PRECEDENCE)) {
5988+
} else if (tokenLevel == ASSIGNMENT_PRECEDENCE) {
59905989
// Right associative, so we recurse at the same precedence
59915990
// level.
59925991
Token next = token.next!;
@@ -6005,7 +6004,7 @@ class Parser {
60056004
: parsePrecedenceExpression(
60066005
next, level, allowCascades, ConstantPatternContext.none);
60076006
listener.handleAssignmentExpression(operator, token);
6008-
} else if (identical(tokenLevel, POSTFIX_PRECEDENCE)) {
6007+
} else if (tokenLevel == POSTFIX_PRECEDENCE) {
60096008
if ((identical(type, TokenType.PLUS_PLUS)) ||
60106009
(identical(type, TokenType.MINUS_MINUS))) {
60116010
listener.handleUnaryPostfixAssignmentExpression(token.next!);
@@ -6014,7 +6013,7 @@ class Parser {
60146013
listener.handleNonNullAssertExpression(next);
60156014
token = next;
60166015
}
6017-
} else if (identical(tokenLevel, SELECTOR_PRECEDENCE)) {
6016+
} else if (tokenLevel == SELECTOR_PRECEDENCE) {
60186017
if (identical(type, TokenType.PERIOD) ||
60196018
identical(type, TokenType.QUESTION_PERIOD)) {
60206019
// Left associative, so we recurse at the next higher precedence
@@ -6350,7 +6349,7 @@ class Parser {
63506349
next = token.next!;
63516350
} while (!identical(mark, token));
63526351

6353-
if (identical(next.type.precedence, ASSIGNMENT_PRECEDENCE)) {
6352+
if (next.type.precedence == ASSIGNMENT_PRECEDENCE) {
63546353
Token assignment = next;
63556354
token = parseExpressionWithoutCascade(next);
63566355
listener.handleAssignmentExpression(assignment, token);
@@ -6693,12 +6692,10 @@ class Parser {
66936692
if (mayParseFunctionExpressions) {
66946693
Token nextToken = next.endGroup!.next!;
66956694
int kind = nextToken.kind;
6696-
if ((identical(kind, FUNCTION_TOKEN) ||
6697-
identical(kind, OPEN_CURLY_BRACKET_TOKEN))) {
6695+
if (kind == FUNCTION_TOKEN || kind == OPEN_CURLY_BRACKET_TOKEN) {
66986696
listener.handleNoTypeVariables(next);
66996697
return parseFunctionExpression(token);
6700-
} else if (identical(kind, KEYWORD_TOKEN) ||
6701-
identical(kind, IDENTIFIER_TOKEN)) {
6698+
} else if (kind == KEYWORD_TOKEN || kind == IDENTIFIER_TOKEN) {
67026699
if (optional('async', nextToken) || optional('sync', nextToken)) {
67036700
listener.handleNoTypeVariables(next);
67046701
return parseFunctionExpression(token);
@@ -6708,8 +6705,7 @@ class Parser {
67086705
// because the user is typing (e.g. `() asy {}`) then continue parsing
67096706
// and allow parseFunctionExpression to report an unexpected token.
67106707
kind = nextToken.next!.kind;
6711-
if ((identical(kind, FUNCTION_TOKEN) ||
6712-
identical(kind, OPEN_CURLY_BRACKET_TOKEN))) {
6708+
if (kind == FUNCTION_TOKEN || kind == OPEN_CURLY_BRACKET_TOKEN) {
67136709
listener.handleNoTypeVariables(next);
67146710
return parseFunctionExpression(token);
67156711
}
@@ -7110,9 +7106,9 @@ class Parser {
71107106
// Scanner ensures `(` has matching `)`.
71117107
Token next = token.next!.endGroup!.next!;
71127108
int kind = next.kind;
7113-
if (!identical(kind, FUNCTION_TOKEN) &&
7114-
!identical(kind, OPEN_CURLY_BRACKET_TOKEN) &&
7115-
(!identical(kind, KEYWORD_TOKEN) ||
7109+
if (kind != FUNCTION_TOKEN &&
7110+
kind != OPEN_CURLY_BRACKET_TOKEN &&
7111+
(kind != KEYWORD_TOKEN ||
71167112
!optional('async', next) && !optional('sync', next))) {
71177113
reportRecoverableErrorWithToken(next, codes.templateUnexpectedToken);
71187114
}
@@ -7508,7 +7504,7 @@ class Parser {
75087504
mayParseFunctionExpressions = true;
75097505
token = parseSingleLiteralString(token);
75107506
int count = 1;
7511-
while (identical(token.next!.kind, STRING_TOKEN)) {
7507+
while (token.next!.kind == STRING_TOKEN) {
75127508
token = parseSingleLiteralString(token);
75137509
count++;
75147510
}
@@ -7559,7 +7555,7 @@ class Parser {
75597555
Token next = token.next!;
75607556
int kind = next.kind;
75617557
while (kind != EOF_TOKEN) {
7562-
if (identical(kind, STRING_INTERPOLATION_TOKEN)) {
7558+
if (kind == STRING_INTERPOLATION_TOKEN) {
75637559
// Parsing ${expression}.
75647560
token = parseExpression(next).next!;
75657561
if (!optional('}', token)) {
@@ -7568,7 +7564,7 @@ class Parser {
75687564
token = next.endGroup!;
75697565
}
75707566
listener.handleInterpolationExpression(next, token);
7571-
} else if (identical(kind, STRING_INTERPOLATION_IDENTIFIER_TOKEN)) {
7567+
} else if (kind == STRING_INTERPOLATION_IDENTIFIER_TOKEN) {
75727568
// Parsing $identifier.
75737569
token = parseIdentifierExpression(next);
75747570
listener.handleInterpolationExpression(next, /* rightBracket = */ null);
@@ -9080,7 +9076,7 @@ class Parser {
90809076
listener.beginSwitchCase(labelCount, expressionCount, begin);
90819077
// Finally zero or more statements.
90829078
int statementCount = 0;
9083-
while (!identical(token.next!.kind, EOF_TOKEN)) {
9079+
while (token.next!.kind != EOF_TOKEN) {
90849080
String? value = peek.stringValue;
90859081
if ((identical(value, 'case')) ||
90869082
(identical(value, 'default')) ||

0 commit comments

Comments
 (0)