diff --git a/benchmark/index.ts b/benchmark/index.ts new file mode 100644 index 00000000..7a1f4b2d --- /dev/null +++ b/benchmark/index.ts @@ -0,0 +1,75 @@ +// eslint-disable-next-line eslint-comments/disable-enable-pair -- ignore +/* eslint-disable require-jsdoc, no-console -- ignore */ +import * as Benchmark from "benchmark" +import fs from "fs" +import { parseForESLint } from "../src/index" +import { parseForESLint as parseOld } from "../node_modules/svelte-eslint-parser" + +const contents = `${fs.readFileSync( + require.resolve("../explorer-v2/src/lib/RulesSettings.svelte"), + "utf-8", +)}// comments` + +type Result = { name: string; hz: number } +const results: Result[] = [] + +function format(hz: number): string { + return (~~(hz * 100) / 100).toString().padEnd(4, " ").padStart(6, " ") +} + +function onCycle(event: { target: Result }): void { + const { name, hz } = event.target + results.push({ name, hz }) + + console.log(event.target.toString()) +} + +function onComplete(): void { + console.log("-".repeat(72)) + const map: Record = {} + for (const result of results) { + const r = (map[result.name.slice(2)] ??= []) + r.push(result.hz) + } + for (const name of Object.keys(map)) { + console.log( + `${name.padEnd(15)} ${format( + map[name].reduce((p, a) => p + a, 0) / map[name].length, + )} ops/sec`, + ) + } + for (let i = 0; i < results.length; ++i) { + const result = results[i] + + console.log(`${result.name.padEnd(15)} ${format(result.hz)} ops/sec`) + } +} + +const suite = new Benchmark.Suite("benchmark", { onCycle, onComplete }) + +for (const no of [1, 2, 3]) { + suite.add(`${no} new svelte-eslint-parser`, function () { + parseForESLint(contents, { + loc: true, + range: true, + raw: true, + tokens: true, + comment: true, + eslintVisitorKeys: true, + eslintScopeManager: true, + }) + }) + suite.add(`${no} old svelte-eslint-parser`, function () { + parseOld(contents, { + loc: true, + range: true, + raw: true, + tokens: true, + comment: true, + eslintVisitorKeys: true, + eslintScopeManager: true, + }) + }) +} + +suite.run() diff --git a/package.json b/package.json index 1d2c0f53..f843771b 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "debug": "mocha --require ts-node/register/transpile-only \"tests/src/**/*.ts\" --reporter dot", "preversion": "npm run lint && npm test", "update-fixtures": "ts-node --transpile-only ./tools/update-fixtures.ts", - "eslint-playground": "eslint tests/fixtures --ext .svelte --config .eslintrc-for-playground.js --format codeframe" + "eslint-playground": "eslint tests/fixtures --ext .svelte --config .eslintrc-for-playground.js --format codeframe", + "benchmark": "ts-node --transpile-only benchmark/index.ts" }, "repository": { "type": "git", @@ -48,7 +49,8 @@ }, "devDependencies": { "@ota-meshi/eslint-plugin": "^0.10.0", - "@ota-meshi/eslint-plugin-svelte": "^0.18.0", + "@ota-meshi/eslint-plugin-svelte": "^0.18.1", + "@types/benchmark": "^2.1.1", "@types/eslint": "^8.0.0", "@types/eslint-scope": "^3.7.0", "@types/eslint-visitor-keys": "^1.0.0", @@ -57,6 +59,7 @@ "@types/semver": "^7.3.9", "@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/parser": "^5.4.0", + "benchmark": "^2.1.4", "code-red": "^0.2.3", "eslint": "^8.2.0", "eslint-config-prettier": "^8.3.0", diff --git a/src/context/index.ts b/src/context/index.ts index 73fdd0ed..d6d23c4e 100644 --- a/src/context/index.ts +++ b/src/context/index.ts @@ -61,6 +61,7 @@ export class ScriptsSourceCode { this.trimmedRaw.slice(end) } } + export type ContextSourceCode = { template: string scripts: ScriptsSourceCode @@ -91,26 +92,28 @@ export class Context { this.parserOptions = parserOptions this.locs = new LinesAndColumns(code) + const spaces = code.replace(/[^\n\r ]/g, " ") + let templateCode = "" let scriptCode = "" let scriptAttrs: Record = {} let start = 0 for (const block of extractBlocks(code)) { - const before = code.slice(start, block.codeRange[0]) - const blankCode = block.code.replace(/[^\n\r ]/g, " ") - templateCode += before + blankCode + templateCode += + code.slice(start, block.codeRange[0]) + + spaces.slice(block.codeRange[0], block.codeRange[1]) if (block.tag === "script") { - scriptCode += before.replace(/[^\n\r ]/g, " ") + block.code + scriptCode += + spaces.slice(start, block.codeRange[0]) + block.code scriptAttrs = Object.assign(scriptAttrs, block.attrs) } else { - scriptCode += before.replace(/[^\n\r ]/g, " ") + blankCode + scriptCode += spaces.slice(start, block.codeRange[1]) } start = block.codeRange[1] } - const after = code.slice(start) - templateCode += after - scriptCode += after.replace(/[^\n\r ]/g, " ") + templateCode += code.slice(start) + scriptCode += spaces.slice(start) this.sourceCode = { template: templateCode, diff --git a/tsconfig.json b/tsconfig.json index e50ab9f2..b82da0f2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,5 +12,10 @@ "noUnusedParameters": true, "esModuleInterop": true }, - "include": ["src/**/*.ts", "tests/**/*.ts", "tools/**/*.ts"] + "include": [ + "src/**/*.ts", + "tests/**/*.ts", + "tools/**/*.ts", + "benchmark/**/*.ts" + ] }