Skip to content

Commit

Permalink
perf: minimize identifier lookahead when parsing let (#13328)
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed May 18, 2021
1 parent f7a9f10 commit 2a5b231
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 11 deletions.
@@ -0,0 +1,22 @@
import Benchmark from "benchmark";
import baseline from "@babel-baseline/parser";
import current from "../../lib/index.js";
import { report } from "../util.mjs";

const suite = new Benchmark.Suite();
function createInput(length) {
return "{ let foecnatsni };".repeat(length);
}
function benchCases(name, implementation, options) {
for (const length of [64, 128, 256, 512]) {
const input = createInput(length);
suite.add(`${name} ${length} let and length-10 binding identifiers`, () => {
implementation.parse(input, options);
});
}
}

benchCases("baseline", baseline);
benchCases("current", current);

suite.on("cycle", report).run();
25 changes: 14 additions & 11 deletions packages/babel-parser/src/parser/statement.js
Expand Up @@ -4,11 +4,7 @@ import * as N from "../types";
import { types as tt, type TokenType } from "../tokenizer/types";
import ExpressionParser from "./expression";
import { Errors, SourceTypeModuleErrors } from "./error";
import {
isIdentifierChar,
isIdentifierStart,
keywordRelationalOperator,
} from "../util/identifier";
import { isIdentifierChar, isIdentifierStart } from "../util/identifier";
import { lineBreak } from "../util/whitespace";
import * as charCodes from "charcodes";
import {
Expand Down Expand Up @@ -49,6 +45,8 @@ const FUNC_NO_FLAGS = 0b000,

const loneSurrogate = /[\uD800-\uDFFF]/u;

const keywordRelationalOperator = /in(?:stanceof)?/y;

/**
* Convert tt.privateName to tt.hash + tt.name for backward Babel 7 compat.
* For performance reasons this routine mutates `tokens`, it is okay
Expand Down Expand Up @@ -183,7 +181,7 @@ export default class StatementParser extends ExpressionParser {
*/
isLetKeyword(context: ?string): boolean {
const next = this.nextTokenStart();
const nextCh = this.input.charCodeAt(next);
const nextCh = this.codePointAtPos(next);
// For ambiguous cases, determine if a LexicalDeclaration (or only a
// Statement) is allowed here. If context is not empty then only a Statement
// is allowed. However, `let [` is an explicit negative lookahead for
Expand All @@ -200,12 +198,17 @@ export default class StatementParser extends ExpressionParser {
if (nextCh === charCodes.leftCurlyBrace) return true;

if (isIdentifierStart(nextCh)) {
let pos = next + 1;
while (isIdentifierChar(this.input.charCodeAt(pos))) {
++pos;
keywordRelationalOperator.lastIndex = next;
const matched = keywordRelationalOperator.exec(this.input);
if (matched !== null) {
// We have seen `in` or `instanceof` so far, now check if the identfier
// ends here
const endCh = this.codePointAtPos(next + matched[0].length);
if (!isIdentifierChar(endCh) && endCh !== charCodes.backslash) {
return false;
}
}
const ident = this.input.slice(next, pos);
if (!keywordRelationalOperator.test(ident)) return true;
return true;
}
return false;
}
Expand Down
@@ -0,0 +1 @@
let in\u0061;
@@ -0,0 +1,30 @@
{
"type": "File",
"start":0,"end":13,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":13}},
"program": {
"type": "Program",
"start":0,"end":13,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":13}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start":0,"end":13,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":13}},
"declarations": [
{
"type": "VariableDeclarator",
"start":4,"end":12,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":12}},
"id": {
"type": "Identifier",
"start":4,"end":12,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":12},"identifierName":"ina"},
"name": "ina"
},
"init": null
}
],
"kind": "let"
}
],
"directives": []
}
}
@@ -0,0 +1 @@
let in饾惉饾惌饾悮饾惂饾悳饾悶饾惃饾悷;
@@ -0,0 +1,30 @@
{
"type": "File",
"start":0,"end":23,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":23}},
"program": {
"type": "Program",
"start":0,"end":23,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":23}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start":0,"end":23,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":23}},
"declarations": [
{
"type": "VariableDeclarator",
"start":4,"end":22,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":22}},
"id": {
"type": "Identifier",
"start":4,"end":22,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":22},"identifierName":"in饾惉饾惌饾悮饾惂饾悳饾悶饾惃饾悷"},
"name": "in饾惉饾惌饾悮饾惂饾悳饾悶饾惃饾悷"
},
"init": null
}
],
"kind": "let"
}
],
"directives": []
}
}
@@ -0,0 +1 @@
let 饾悽饾惂;
@@ -0,0 +1,30 @@
{
"type": "File",
"start":0,"end":9,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":9}},
"program": {
"type": "Program",
"start":0,"end":9,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":9}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "VariableDeclaration",
"start":0,"end":9,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":9}},
"declarations": [
{
"type": "VariableDeclarator",
"start":4,"end":8,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":8}},
"id": {
"type": "Identifier",
"start":4,"end":8,"loc":{"start":{"line":1,"column":4},"end":{"line":1,"column":8},"identifierName":"饾悽饾惂"},
"name": "饾悽饾惂"
},
"init": null
}
],
"kind": "let"
}
],
"directives": []
}
}

0 comments on commit 2a5b231

Please sign in to comment.