Skip to content

Commit

Permalink
Add a script to easily test Sucrase perf on a project (#341)
Browse files Browse the repository at this point in the history
This should make it easier to benchmark and profile real-world code.
  • Loading branch information
alangpierce authored Nov 18, 2018
1 parent e460053 commit 41476b0
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 40 deletions.
66 changes: 66 additions & 0 deletions benchmark/benchmark-project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env node
/* eslint-disable no-console */
import parseArgs from "yargs-parser";

// @ts-ignore: May not be built, just ignore for now.
import * as sucrase from "../dist/index"; // eslint-disable-line import/no-unresolved
import {FileInfo, loadProjectFiles} from "./loadProjectFiles";

async function main(): Promise<void> {
const args = parseArgs(process.argv.slice(2), {boolean: ["profile"]});
const projectPath = args._[0];
const shouldProfile = args.profile;
const numTimes = args.times || 1;

const projectFiles = await loadProjectFiles(projectPath);
if (numTimes === 1) {
console.log(`Running Sucrase on ${projectPath}`);
} else {
console.log(`Running Sucrase ${numTimes} times on ${projectPath}`);
}
const totalLines = projectFiles
.map(({code}) => code.split("\n").length)
.reduce((a, b) => a + b, 0);
console.log(`Found ${projectFiles.length} files with ${totalLines} lines`);

if (shouldProfile) {
console.log(`Make sure you have Chrome DevTools for Node open.`);
// tslint:disable-next-line no-any
(console as any).profile(`Sucrase ${projectPath}`);
for (let i = 0; i < numTimes; i++) {
for (const fileInfo of projectFiles) {
runTransform(fileInfo);
}
}
// tslint:disable-next-line no-any
(console as any).profileEnd(`Sucrase ${projectPath}`);
} else {
const startTime = process.hrtime();
for (let i = 0; i < numTimes; i++) {
for (const fileInfo of projectFiles) {
runTransform(fileInfo);
}
}
const totalTime = process.hrtime(startTime);
const timeSeconds = totalTime[0] + totalTime[1] / 1e9;
console.log(`Time taken: ${Math.round(timeSeconds * 1000) / 1000}s`);
console.log(`Speed: ${Math.round((totalLines * numTimes) / timeSeconds)} lines per second`);
}
}

function runTransform({code, path}: FileInfo): void {
if (path.endsWith(".js") || path.endsWith(".jsx")) {
sucrase.transform(code, {transforms: ["jsx", "imports", "flow"], filePath: path});
} else if (path.endsWith(".ts")) {
sucrase.transform(code, {transforms: ["imports", "typescript"], filePath: path});
} else if (path.endsWith(".tsx")) {
sucrase.transform(code, {transforms: ["jsx", "imports", "typescript"], filePath: path});
} else {
throw new Error(`Unrecognized file type: ${path}`);
}
}

main().catch((e) => {
console.error(e);
process.exitCode = 1;
});
12 changes: 9 additions & 3 deletions benchmark/benchmark-react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import * as babel from "@babel/core";

// @ts-ignore: May not be built, just ignore for now.
import * as sucrase from "../dist/index"; // eslint-disable-line import/no-unresolved
import {loadReactFiles} from "./loadReactFiles";
import {loadProjectFiles} from "./loadProjectFiles";

async function main(): Promise<void> {
console.log(`Compiling React codebase:`);
const reactFiles = await loadReactFiles();
const reactFiles = await loadProjectFiles("./example-runner/example-repos/react/packages");
console.time("Sucrase");
for (const {code, path} of reactFiles) {
if (path.endsWith(".ts")) {
continue;
}
sucrase.transform(code, {
transforms: ["jsx", "imports", "flow"],
filePath: path,
Expand All @@ -20,7 +23,10 @@ async function main(): Promise<void> {
console.timeEnd("Sucrase");

console.time("Babel");
for (const {code} of reactFiles) {
for (const {code, path} of reactFiles) {
if (path.endsWith(".ts")) {
continue;
}
babel.transform(code, {
presets: ["@babel/preset-react", "@babel/preset-flow"],
plugins: [
Expand Down
11 changes: 8 additions & 3 deletions benchmark/loadReactFiles.ts → benchmark/loadProjectFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export interface FileInfo {
code: string;
}

export async function loadReactFiles(): Promise<Array<FileInfo>> {
export async function loadProjectFiles(projectPath: string): Promise<Array<FileInfo>> {
const results: Array<FileInfo> = [];
async function visit(path: string): Promise<void> {
for (const child of await readdir(path)) {
Expand All @@ -16,12 +16,17 @@ export async function loadReactFiles(): Promise<Array<FileInfo>> {
const childPath = join(path, child);
if ((await stat(childPath)).isDirectory()) {
await visit(childPath);
} else if (childPath.endsWith(".js")) {
} else if (
childPath.endsWith(".js") ||
childPath.endsWith(".jsx") ||
childPath.endsWith(".ts") ||
childPath.endsWith(".tsx")
) {
const code = (await readFile(childPath)).toString();
results.push({code, path: childPath});
}
}
}
await visit("./example-runner/example-repos/react/packages");
await visit(projectPath);
return results;
}
27 changes: 0 additions & 27 deletions benchmark/profile-react.ts

This file was deleted.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
"generate": "sucrase-node generator/generate.ts",
"benchmark": "sucrase-node benchmark/benchmark.ts",
"benchmark-react": "sucrase-node benchmark/benchmark-react.ts",
"benchmark-project": "sucrase-node benchmark/benchmark-project.ts",
"lint": "sucrase-node script/lint.ts",
"profile": "node --inspect-brk ./node_modules/.bin/sucrase-node ./benchmark/profile",
"profile-react": "node --inspect-brk ./node_modules/.bin/sucrase-node ./benchmark/profile-react.ts",
"profile-project": "node --inspect-brk ./node_modules/.bin/sucrase-node ./benchmark/benchmark-project.ts --profile",
"prepublishOnly": "yarn clean && yarn build",
"release": "sucrase-node script/release.ts",
"run-examples": "sucrase-node example-runner/example-runner.ts",
Expand Down Expand Up @@ -54,7 +55,8 @@
"@babel/preset-typescript": "7.0.0-beta.51",
"@types/mocha": "^2.2.43",
"@types/mz": "^0.0.32",
"@types/node": "^8.0.31",
"@types/node": "^10.12.9",
"@types/yargs-parser": "^11.0.0",
"codecov": "^3.1.0",
"eslint": "^4.13.1",
"eslint-config-airbnb-base": "^12.1.0",
Expand All @@ -69,7 +71,8 @@
"tslint": "^5.9.1",
"tslint-language-service": "^0.9.9",
"typescript": "^2.9.1",
"typescript-eslint-parser": "^16.0.0"
"typescript-eslint-parser": "^16.0.0",
"yargs-parser": "^11.1.0"
},
"dependencies": {
"commander": "^2.12.2",
Expand Down
34 changes: 30 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,22 @@
version "10.5.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.4.tgz#6eccc158504357d1da91434d75e86acde94bb10b"

"@types/node@^8.0.31":
version "8.10.22"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.22.tgz#c095d7c668908d48b95ae11fcc4a6d6b1c116a35"
"@types/node@^10.12.9":
version "10.12.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.9.tgz#a07bfa74331471e1dc22a47eb72026843f7b95c8"
integrity sha512-eajkMXG812/w3w4a1OcBlaTwsFPO5F7fJ/amy+tieQxEMWBlbV1JGSjkFM+zkHNf81Cad+dfIRA+IBkvmvdAeA==

"@types/yargs-parser@^11.0.0":
version "11.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-11.0.0.tgz#514933c83ec38b8e06b8c9e5ffff637f20474f2e"
integrity sha512-ZfKjiy9zRHQWWRiQLeushSHE2IgHJ8U/OaABsNodkuufZoWED7Plz6egREZiE8dfrTAnrD8Rw/kUh2S6Iu1W0w==
dependencies:
"@types/yargs" "*"

"@types/yargs@*":
version "12.0.1"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.1.tgz#c5ce4ad64499010ae4dc2acd9b14d49749a44233"
integrity sha512-UVjo2oH79aRNcsDlFlnQ/iJ67Jd7j6uSg7jUJP/RZ/nUjAh5ElmnwlD5K/6eGgETJUgCHkiWn91B8JjXQ6ubAw==

abbrev@1:
version "1.1.1"
Expand Down Expand Up @@ -612,6 +625,11 @@ camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"

camelcase@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42"
integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==

caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
Expand Down Expand Up @@ -848,7 +866,7 @@ debug@^3.1.0:
dependencies:
ms "2.0.0"

decamelize@^1.0.0, decamelize@^1.1.1:
decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"

Expand Down Expand Up @@ -3240,6 +3258,14 @@ yallist@^3.0.0, yallist@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"

yargs-parser@^11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.0.tgz#0b8104116367bf663089b24e5801438ab50396a3"
integrity sha512-lGA5HsbjkpCfekDBHAhgE5OE8xEoqiUDylowr+BvhRCwG1xVYTsd8hx2CYC0NY4k9RIgJeybFTG2EZW4P2aN1w==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"

yargs-parser@^8.0.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950"
Expand Down

0 comments on commit 41476b0

Please sign in to comment.