Skip to content

Commit

Permalink
feat(all): added benchmark
Browse files Browse the repository at this point in the history
Note: This benchmark only compare Meriyah vs Cherow
  • Loading branch information
KFlash committed May 31, 2019
1 parent 9092515 commit 8a525b3
Show file tree
Hide file tree
Showing 15 changed files with 162 additions and 18 deletions.
1 change: 1 addition & 0 deletions bench/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
27 changes: 27 additions & 0 deletions bench/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "bench",
"private": true,
"license": "ISC",
"scripts": {
"postinstall": "cd .. && npm run bundle:bench && cd bench",
"parse": "ts-node -r esm src/parse.ts module",
"parse:loc": "ts-node -r esm src/parse.ts module,loc"
},
"devDependencies": {
"@types/node": "10.12.18",
"@types/benchmark": "1.0.31",
"cherow": "dev",
"cross-env": "5.2.0",
"benchmark": "2.1.4",
"esm": "3.2.4",
"ts-node": "7.0.1",
"tsconfig-paths": "3.7.0",
"typescript": "3.2.2",
"jquery": "3.3.1",
"react": "16.8.2",
"vue": "2.6.6",
"angular": "1.7.7",
"@aurelia/jit-html-browser": "0.3.0-dev.20190112",
"inferno": "7.1.7"
}
}
2 changes: 2 additions & 0 deletions bench/src/cherow/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { master } from './master';
export { local } from './local';
5 changes: 5 additions & 0 deletions bench/src/cherow/local.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as cherow from '../../../dist/meriyah.cjs';

export const local = {
cherow
};
5 changes: 5 additions & 0 deletions bench/src/cherow/master.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as cherow from 'cherow';

export const master = {
cherow
};
82 changes: 82 additions & 0 deletions bench/src/parse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import * as Benchmark from 'benchmark';
import * as path from 'path';
import * as fs from 'fs';
import { master, local } from './cherow/index';

const optionNames = process.argv.slice(2)[0];
const options = optionNames.split(',').reduce((acc, cur) => {
acc[cur] = true;
return acc;
}, {});

const node_modules = path.resolve('node_modules');
const files = {
typescript: fs.readFileSync(path.join(node_modules, 'typescript', 'lib', 'tsc.js')).toString(),
angular: fs.readFileSync(path.join(node_modules, 'angular', 'angular.js')).toString(),
react: fs.readFileSync(path.join(node_modules, 'react', 'umd', 'react.development.js')).toString(),
jquery: fs.readFileSync(path.join(node_modules, 'jquery', 'dist', 'jquery.js')).toString(),
vue: fs.readFileSync(path.join(node_modules, 'vue', 'dist', 'vue.js')).toString(),
inferno: fs.readFileSync(path.join(node_modules, 'inferno', 'dist', 'index.esnext.js')).toString(),
aurelia: fs
.readFileSync(path.join(node_modules, '@aurelia', 'jit-html-browser', 'dist', 'index.iife.full.js'))
.toString()
};

type Result = { name: string; hz: number };
const results: {
1: Result[];
2: Result[];
} = {
1: [],
2: []
};

const format = function format(hz: number): string {
return (~~(hz * 100) / 100)
.toString()
.padEnd(4, ' ')
.padStart(6, ' ');
};

const onCycle = function onCycle(event: any): void {
const { name, hz } = event.target;
const version = name.slice(1, 2);
results[version].push({ name: name.slice(3), hz });

console.log(event.target.toString());
};

const onComplete = function onComplete(): void {
console.log('-'.repeat(72));
console.log(`${' '.repeat(42)} cherow${' '.repeat(20)} meriyah${' '.repeat(10)}`);
for (let i = 0; i < results[1].length; ++i) {
const v1 = results[1][i];
const v2 = results[2][i];

const diff = ~~((Math.max(v1.hz, v2.hz) / Math.min(v1.hz, v2.hz) - 1) * 100);
const diffText = `${v1.hz < v2.hz ? '\x1b[32m' : '\x1b[31m'}${diff}%\x1b[0m`;

console.log(
`${v1.name.padEnd(32)} ${format(v1.hz)} ops/sec${' '.repeat(8)} ${format(v2.hz)} ops/sec${' '.repeat(
8
)}${diffText}`
);
}
};

const suite = new Benchmark.Suite(optionNames, { onCycle, onComplete });

for (const name in files) {
const source = files[name];
suite.add(`v1 ${name.padEnd(14, ' ')} ${optionNames}`, function() {
master.cherow.parse(source, options);
});
}
for (const name in files) {
const source = files[name];
suite.add(`v2 ${name.padEnd(14, ' ')} ${optionNames}`, function() {
local.cherow.parse(source, options);
});
}

suite.run();
12 changes: 12 additions & 0 deletions bench/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"lib": ["esnext"],
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"pretty": true,
"target": "es2018",
"types": ["node", "benchmark"]
},
"include": ["src"]
}
3 changes: 3 additions & 0 deletions bench/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"rules": {}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "meriyah",
"version": "0.2.1",
"version": "0.2.2",
"description": "A 100% compliant, self-hosted javascript parser with high focus on both performance and stability",
"main": "dist/meriyah.umd.js",
"module": "dist/meriyah.esm.js",
Expand Down
2 changes: 1 addition & 1 deletion src/lexer/comments.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { nextCodePoint, CharTypes, CharFlags, ScannerState, Seek } from './';
import { nextCodePoint, CharTypes, CharFlags, ScannerState } from './';
import { Chars } from '../chars';
import { ParserState, Flags } from '../common';
import { report, Errors } from '../errors';
Expand Down
5 changes: 0 additions & 5 deletions src/lexer/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ import { ParserState } from '../common';
import { unicodeLookup } from '../unicode';
import { report, Errors } from '../errors';

export const enum Seek {
None,
SameLine,
NewLine
}
export const enum ScannerState {
None = 0,
NewLine = 1 << 0,
Expand Down
3 changes: 1 addition & 2 deletions src/lexer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ export {
isExoticECMAScriptWhitespace,
fromCodePoint,
toHex,
ScannerState,
Seek
ScannerState
} from './common';
export { CharTypes, CharFlags, isIdentifierStart, isIdentifierPart } from './charClassifier';
export { scanIdentifier, scanPrivateName, scanUnicodeEscapeValue } from './identifier';
Expand Down
2 changes: 1 addition & 1 deletion src/lexer/scan.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { skipSingleLineComment, skipMultiLineComment, ScannerState, Seek } from './';
import { skipSingleLineComment, skipMultiLineComment, ScannerState } from './';
import { CharTypes, CharFlags } from './charClassifier';
import { Chars } from '../chars';
import { Token } from '../token';
Expand Down
21 changes: 14 additions & 7 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export function parseStatementList(parser: ParserState, context: Context): ESTre
context |= Context.Strict;
}
}
statements.push(parseDirective(parser, context, expr, tokenIndex, token));
statements.push(parseDirective(parser, context, expr, token, tokenIndex));
}

while (parser.token !== Token.EOF) {
Expand Down Expand Up @@ -252,7 +252,7 @@ export function parseparseModuleItemList(
context |= Context.Strict;
}
}
statements.push(parseDirective(parser, context, expr, tokenIndex, token));
statements.push(parseDirective(parser, context, expr, token, tokenIndex));
}
}

Expand Down Expand Up @@ -873,28 +873,35 @@ export function parseAsyncArrowOrAsyncFunctionDeclaration(
*
* @param parser Parser object
* @param context Context masks
* @param expression AST expression node
* @param token
* @param start Start pos of node
*/

export function parseDirective(
parser: ParserState,
context: Context,
expression: any,
start: number,
token: Token
token: Token,
start: number
): ESTree.ExpressionStatement {
const { tokenRaw } = parser;

if (token !== Token.Semicolon) {
parser.assignable = AssignmentKind.CannotAssign;

expression = parseMemberOrUpdateExpression(parser, context, expression, 0, 0, start);

if (parser.token !== Token.Semicolon) {
expression = parseAssignmentExpression(parser, context, start, expression);

if (parser.token === Token.Comma) {
expression = parseSequenceExpression(parser, context, start, expression);
}
}
}

consumeSemicolon(parser, context | Context.AllowRegExp);
consumeSemicolon(parser, context | Context.AllowRegExp);
}

return context & Context.OptionsDirectives
? finishNode(parser, context, start, {
Expand Down Expand Up @@ -2607,7 +2614,7 @@ export function parseFunctionBody(
}
}
}
body.push(parseDirective(parser, context, expr, tokenIndex, token));
body.push(parseDirective(parser, context, expr, token, tokenIndex));
}

if (
Expand Down
8 changes: 7 additions & 1 deletion test/parser/miscellaneous/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ describe('Miscellaneous - Directives', () => {
"'random\\u00a\\ foo'",
"'random\\uax foo'",
"'random\\u0au foo'",
'"use strict" "Hello\\312World"',
'"use strict" \\1',
'"use strict" "\\1"',
'"use strict"; "\\1";',
'"use strict" ++',
'function foo() { "use strict"; with (a) b = c; }',
'"use strict"; function foo() { with (a) b = c; }',
'"use strict"; function hello() { "\\000"; }',
Expand Down Expand Up @@ -130,7 +135,8 @@ describe('Miscellaneous - Directives', () => {
'"use strict" \n "Hello\\312World"',
'"use strict" + "Hello\\312World"',
'"use strict", "Hello\\312World"',
'"use strict", "Hello\\312World"'
'"use strict", "Hello\\312World"',
'function foo() { "use strict" .foo }'
]) {
it(`/* comment in front */ ${arg}`, () => {
t.doesNotThrow(() => {
Expand Down

0 comments on commit 8a525b3

Please sign in to comment.