From 9dac37c60804c38fe4e6e8888768b39a097d865b Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Wed, 26 Feb 2025 16:06:02 +0800 Subject: [PATCH] Replace `benchmark` with `tinybench` (#17132) --- CONTRIBUTING.md | 4 +-- package.json | 2 +- scripts/build/config.js | 2 +- src/cli/format.js | 34 ++++++------------- .../__tests__/performance-flags.js | 2 +- yarn.lock | 28 +++++---------- 6 files changed, 24 insertions(+), 48 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8db04091..c3fecae10 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -85,13 +85,13 @@ If you want to know more about Prettier's GitHub labels, see the [Issue Labels]( If you're contributing a performance improvement, the following Prettier CLI options can help: - `--debug-repeat N` uses a naïve loop to repeat the formatting `N` times and measures the average run duration. It can be useful to highlight hot functions in the profiler. This can also set by environment variable `PRETTIER_PERF_REPEAT`. -- `--debug-benchmark` uses [`benchmark`](https://npm.im/benchmark) module to produce statistically significant duration measurements. +- `--debug-benchmark` uses [`tinybench`](https://www.npmjs.com/package/tinybench) module to produce statistically significant duration measurements. For convenience, the following commands for profiling are available via [`package.json`](package.json) `scripts`. - `PRETTIER_PERF_REPEAT=1000 yarn perf ` starts the naïve loop. See the CLI output for when the measurements finish, and stop profiling at that moment. - `PRETTIER_PERF_REPEAT=1000 yarn perf:inspect ` starts the naïve loop with `node --inspect-brk` flag that pauses execution and waits for Chromium/Chrome/Node Inspector to attach. Open [`chrome://inspect`](chrome://inspect), select the process to inspect, and activate the CPU Profiler, this will unpause execution. See the CLI output for when the measurements finish, and stop the CPU Profiler at that moment to avoid collecting more data than needed. -- `yarn perf:benchmark ` starts the `benchmark`-powered measurements. See the CLI output for when the measurements finish. +- `yarn perf:benchmark ` starts the measurements. See the CLI output for when the measurements finish. In the above commands: diff --git a/package.json b/package.json index 4c6e31ab2..bb33ad18d 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,6 @@ "@stylistic/eslint-plugin-js": "4.0.1", "@types/estree": "1.0.6", "@typescript-eslint/eslint-plugin": "8.25.0", - "benchmark": "2.1.4", "browserslist": "4.24.4", "browserslist-to-esbuild": "2.1.1", "c8": "10.1.3", @@ -150,6 +149,7 @@ "serialize-javascript": "6.0.2", "snapshot-diff": "0.10.0", "tempy": "3.1.0", + "tinybench": "3.1.1", "ts-expect": "1.3.0" }, "resolutions": { diff --git a/scripts/build/config.js b/scripts/build/config.js index 6cd6a9a41..280470fd7 100644 --- a/scripts/build/config.js +++ b/scripts/build/config.js @@ -807,7 +807,7 @@ const nodejsFiles = [ { input: "src/cli/index.js", outputBaseName: "internal/cli", - external: ["benchmark"], + external: ["tinybench"], // TODO: Remove this when we drop support for Node.js v16 replaceModule: [ { diff --git a/src/cli/format.js b/src/cli/format.js index 25d0e7aa6..f568c9826 100644 --- a/src/cli/format.js +++ b/src/cli/format.js @@ -166,40 +166,26 @@ async function format(context, input, opt) { const { performanceTestFlag } = context; if (performanceTestFlag?.debugBenchmark) { - let benchmark; + let Bench; try { - ({ default: benchmark } = await import("benchmark")); + ({ Bench } = await import("tinybench")); } catch { context.logger.debug( - "'--debug-benchmark' requires the 'benchmark' package to be installed.", + "'--debug-benchmark' requires the 'tinybench' package to be installed.", ); process.exit(2); } context.logger.debug( - "'--debug-benchmark' option found, measuring formatWithCursor with 'benchmark' module.", + "'--debug-benchmark' option found, measuring formatWithCursor with 'tinybench' module.", ); - const suite = new benchmark.Suite(); - suite.add("format", { - defer: true, - async fn(deferred) { - await prettier.formatWithCursor(input, opt); - deferred.resolve(); - }, - }); - const result = await new Promise((resolve) => { - suite - .on("complete", (event) => { - resolve({ - benchmark: String(event.target), - hz: event.target.hz, - ms: event.target.times.cycle * 1000, - }); - }) - .run({ async: false }); - }); + const bench = new Bench(); + bench.add("Format", () => prettier.formatWithCursor(input, opt)); + await bench.run(); + + const [result] = bench.table(); context.logger.debug( "'--debug-benchmark' measurements for formatWithCursor: " + - JSON.stringify(result, null, 2), + JSON.stringify(result, undefined, 2), ); } else if (performanceTestFlag?.debugRepeat) { const repeat = performanceTestFlag.debugRepeat; diff --git a/tests/integration/__tests__/performance-flags.js b/tests/integration/__tests__/performance-flags.js index c5de6772c..20b9cc662 100644 --- a/tests/integration/__tests__/performance-flags.js +++ b/tests/integration/__tests__/performance-flags.js @@ -7,7 +7,7 @@ describe("should not write file or print code when `--debug-benchmark` or `--deb ).toBe(true); }; - // Can't test `--debug-benchmark`, since it requires `benchmark` package + // Can't test `--debug-benchmark`, since it requires `tinybench` package runCli( "cli/performance-flags", ["--debug-repeat", "2", "--parser", "babel"], diff --git a/yarn.lock b/yarn.lock index 0b6a2f3ab..afde77331 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2577,16 +2577,6 @@ __metadata: languageName: node linkType: hard -"benchmark@npm:2.1.4": - version: 2.1.4 - resolution: "benchmark@npm:2.1.4" - dependencies: - lodash: "npm:^4.17.4" - platform: "npm:^1.3.3" - checksum: 10/0f42f865aeb8b79992bb6204874312f9cb384e122f4fd3b20ba6d0bc7cff003610400fb37e52580a7b4aec4a3d1291c51b5ff887691b1abc80e9df4ff032a675 - languageName: node - linkType: hard - "birecord@npm:^0.1.1": version: 0.1.1 resolution: "birecord@npm:0.1.1" @@ -6026,7 +6016,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.4, lodash@npm:~4.17.21": +"lodash@npm:~4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 @@ -6783,13 +6773,6 @@ __metadata: languageName: node linkType: hard -"platform@npm:^1.3.3": - version: 1.3.6 - resolution: "platform@npm:1.3.6" - checksum: 10/1f2d8333e23ea6a7620c828d2fc1ccbbd33e01928fb142323420506114d7325ebdeb1b38544efbf64e90ab73af0847f874d0f475b9327bcf53510fa827a4ef95 - languageName: node - linkType: hard - "please-upgrade-node@npm:3.2.0": version: 3.2.0 resolution: "please-upgrade-node@npm:3.2.0" @@ -6903,7 +6886,6 @@ __metadata: acorn-jsx: "npm:5.3.2" angular-estree-parser: "npm:10.2.0" angular-html-parser: "npm:8.0.1" - benchmark: "npm:2.1.4" browserslist: "npm:4.24.4" browserslist-to-esbuild: "npm:2.1.1" c8: "npm:10.1.3" @@ -6994,6 +6976,7 @@ __metadata: snapshot-diff: "npm:0.10.0" strip-ansi: "npm:7.1.0" tempy: "npm:3.1.0" + tinybench: "npm:3.1.1" to-fast-properties: "npm:4.0.0" ts-expect: "npm:1.3.0" typescript: "npm:5.7.3" @@ -7908,6 +7891,13 @@ __metadata: languageName: node linkType: hard +"tinybench@npm:3.1.1": + version: 3.1.1 + resolution: "tinybench@npm:3.1.1" + checksum: 10/1d97035722dd91fc8a496cb2a97c375a06ce2ec03e57586ee5bf4b861bbc8a3ab52839d285ca5948c094ac61c1529fbdf7f47c9cb7e8dce11daafd4239eb47b0 + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.10": version: 0.2.10 resolution: "tinyglobby@npm:0.2.10"