From 77d57991ee844c2cd0b98841c6967afc0ac68143 Mon Sep 17 00:00:00 2001 From: Jon Koops Date: Sat, 23 Dec 2023 22:35:04 +0100 Subject: [PATCH] Replace `benchmark` with `tinybench` (#334) --- benchmarks/benchmarks.js | 72 ++++++++++++++++++++++++++++++++++++++ benchmarks/fixtures.js | 29 --------------- benchmarks/index.html | 3 +- benchmarks/package.json | 7 ++-- benchmarks/run.js | 30 ++-------------- benchmarks/runChecks.js | 15 -------- benchmarks/runInBrowser.js | 53 +++------------------------- benchmarks/runSuite.js | 41 ---------------------- package-lock.json | 27 +++++--------- 9 files changed, 91 insertions(+), 186 deletions(-) create mode 100644 benchmarks/benchmarks.js delete mode 100644 benchmarks/fixtures.js delete mode 100644 benchmarks/runChecks.js delete mode 100644 benchmarks/runSuite.js diff --git a/benchmarks/benchmarks.js b/benchmarks/benchmarks.js new file mode 100644 index 0000000..4014eb4 --- /dev/null +++ b/benchmarks/benchmarks.js @@ -0,0 +1,72 @@ +import { Bench } from 'tinybench'; + +import local from 'classnames-local'; +import dedupe from 'classnames-local/dedupe.js'; +import localPackage from 'classnames-local/package.json' with { type: 'json' }; + +import npm from 'classnames-npm'; +import npmDedupe from 'classnames-npm/dedupe.js'; +import npmPackage from 'classnames-npm/package.json' with { type: 'json' }; + +if (localPackage.version !== npmPackage.version) { + console.warn( + `Your local version (${localPackage.version}) does not match the installed version (${npmPackage.version}).\n\n` + + 'Please run `npm update classnames-npm` in ./benchmarks to ensure you are benchmarking against the latest version published to NPM.\n' + ); +} + +const benchmarks = [ + { + description: 'strings', + args: ['one', 'two', 'three'] + }, + { + description: 'object', + args: [{one: true, two: true, three: false}] + }, + { + description: 'strings, object', + args: ['one', 'two', {four: true, three: false}] + }, + { + description: 'mix', + args: ['one', {two: true, three: false}, {four: 'four', five: true}, 6, {}] + }, + { + description: 'arrays', + args: [['one', 'two'], ['three'], ['four', ['five']], [{six: true}, {seven: false}]] + } +]; + +export async function runBenchmarks () { + for (const benchmark of benchmarks) { + console.log(`Benchmarking '${benchmark.description}'.`); + const bench = await runBenchmark(benchmark); + console.table(bench.table()); + } + + console.log('Finished!'); +} + +async function runBenchmark (benchmark) { + const bench = new Bench(); + + bench.add(`local#${benchmark.description}`, () => { + local(...benchmark.args); + }); + + bench.add(`npm#${benchmark.description}`, () => { + npm(...benchmark.args); + }); + + bench.add(`local/dedupe#${benchmark.description}`, () => { + dedupe(...benchmark.args); + }); + + bench.add(`npm/dedupe#${benchmark.description}`, () => { + npmDedupe(...benchmark.args); + }); + + await bench.run(); + return bench; +} diff --git a/benchmarks/fixtures.js b/benchmarks/fixtures.js deleted file mode 100644 index 6d8cd59..0000000 --- a/benchmarks/fixtures.js +++ /dev/null @@ -1,29 +0,0 @@ -const fixtures = [ - { - description: 'strings', - args: ['one', 'two', 'three'], - expected: 'one two three' - }, - { - description: 'object', - args: [{one: true, two: true, three: false}], - expected: 'one two' - }, - { - description: 'strings, object', - args: ['one', 'two', {four: true, three: false}], - expected: 'one two four' - }, - { - description: 'mix', - args: ['one', {two: true, three: false}, {four: 'four', five: true}, 6, {}], - expected: 'one two four five 6' - }, - { - description: 'arrays', - args: [['one', 'two'], ['three'], ['four', ['five']], [{six: true}, {seven: false}]], - expected: 'one two three four five six' - } -]; - -export default fixtures; diff --git a/benchmarks/index.html b/benchmarks/index.html index 351bafe..19d836e 100644 --- a/benchmarks/index.html +++ b/benchmarks/index.html @@ -5,8 +5,7 @@ Benchmarks - -

+		
 		
 	
 
diff --git a/benchmarks/package.json b/benchmarks/package.json
index 32d6193..79814f2 100644
--- a/benchmarks/package.json
+++ b/benchmarks/package.json
@@ -3,17 +3,16 @@
   "type": "module",
   "scripts": {
     "benchmarks": "node ./run.js",
-    "benchmarks-browser": "rollup --plugin commonjs,json,node-resolve ./runInBrowser.js --file ./runInBrowser.bundle.js && http-server -o -c-1"
+    "benchmarks-browser": "rollup --plugin commonjs,json,node-resolve ./runInBrowser.js --file ./runInBrowser.bundle.js && http-server -c-1"
   },
   "devDependencies": {
     "@rollup/plugin-commonjs": "^25.0.7",
     "@rollup/plugin-json": "^6.1.0",
     "@rollup/plugin-node-resolve": "^15.2.3",
-    "benchmark": "^2.1.4",
     "classnames-local": "file:../",
     "classnames-npm": "npm:classnames@*",
     "http-server": "^14.1.1",
-    "lodash": "^4.17.21",
-    "rollup": "^4.9.1"
+    "rollup": "^4.9.1",
+    "tinybench": "^2.5.1"
   }
 }
diff --git a/benchmarks/run.js b/benchmarks/run.js
index d2d06ac..e9e2240 100644
--- a/benchmarks/run.js
+++ b/benchmarks/run.js
@@ -1,29 +1,3 @@
-import local from 'classnames-local';
-import dedupe from 'classnames-local/dedupe.js';
-import localPackage from 'classnames-local/package.json' with { type: 'json' };
+import { runBenchmarks } from './benchmarks.js';
 
-import npm from 'classnames-npm';
-import npmDedupe from 'classnames-npm/dedupe.js';
-import npmPackage from 'classnames-npm/package.json' with { type: 'json' };
-
-import fixtures from './fixtures.js';
-import runChecks from './runChecks.js';
-import runSuite from './runSuite.js';
-
-if (localPackage.version !== npmPackage.version) {
-	log(
-		`Your local version (${localPackage.version} does not match the installed version (${npmPackage.version})\n\n` +
-		'Please run `npm update classnames-npm` in ./benchmarks to ensure you are benchmarking\n' +
-		'the latest version of this package.\n'
-	);
-	process.exit(0);
-}
-
-fixtures.forEach((f) => {
-	runChecks(local, npm, dedupe, npmDedupe, f);
-	runSuite(local, npm, dedupe, npmDedupe, f, log);
-});
-
-function log (message) {
-	console.log(message);
-}
+await runBenchmarks();
diff --git a/benchmarks/runChecks.js b/benchmarks/runChecks.js
deleted file mode 100644
index 42b4f27..0000000
--- a/benchmarks/runChecks.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import assert from 'node:assert/strict';
-
-function sortClasses (str) {
-	return str.split(' ').sort().join(' ');
-}
-
-function runChecks (local, npm, dedupe, npmDedupe, fixture) {
-	// Sort assertions because 'dedupe' returns results in a different order.
-	assert.equal(sortClasses(local(...fixture.args)), sortClasses(fixture.expected));
-	assert.equal(sortClasses(dedupe(...fixture.args)), sortClasses(fixture.expected));
-	assert.equal(sortClasses(npm(...fixture.args)), sortClasses(fixture.expected));
-	assert.equal(sortClasses(npmDedupe(...fixture.args)), sortClasses(fixture.expected));
-}
-
-export default runChecks;
diff --git a/benchmarks/runInBrowser.js b/benchmarks/runInBrowser.js
index c5b1480..33a8dbf 100644
--- a/benchmarks/runInBrowser.js
+++ b/benchmarks/runInBrowser.js
@@ -1,52 +1,9 @@
-import local from 'classnames-local';
-import dedupe from 'classnames-local/dedupe.js';
-import localPackage from 'classnames-local/package.json' with { type: 'json' };
-
-import npm from 'classnames-npm';
-import npmDedupe from 'classnames-npm/dedupe.js';
-import npmPackage from 'classnames-npm/package.json' with { type: 'json' };
-
-import fixtures from './fixtures.js';
-import runSuite from './runSuite.js';
+import { runBenchmarks } from './benchmarks.js';
 
 const startButton = document.getElementById('start');
-const results = document.getElementById('results');
-
-startButton.addEventListener('click', runBenchmarks);
 
-if (localPackage.version === npmPackage.version) {
+startButton.addEventListener('click', async () => {
+	startButton.disabled = true;
+	await runBenchmarks();
 	startButton.disabled = false;
-} else {
-	startButton.style.display = 'none';
-
-	log(
-		`Your local version (${localPackage.version} does not match the installed version (${npmPackage.version})\n\n` +
-		'Please run `npm update classnames-npm` in ./benchmarks to ensure you are benchmarking\n' +
-		'the latest version of this package.\n'
-	);
-}
-
-async function runBenchmarks () {
-	startButton.style.display = 'none';
-
-	log('Running benchmark…');
-	log(navigator.userAgent);
-
-	await nextTick();
-
-	for (const fixture of fixtures) {
-		runSuite(local, npm, dedupe, npmDedupe, fixture, log);
-		await nextTick();
-	}
-
-	log('Finished!');
-}
-
-function log (message) {
-	console.log(message);
-	results.textContent += `${message}\n`;
-}
-
-function nextTick () {
-	return new Promise((resolve) => setTimeout(resolve));
-}
+});
diff --git a/benchmarks/runSuite.js b/benchmarks/runSuite.js
deleted file mode 100644
index cc6da57..0000000
--- a/benchmarks/runSuite.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import benchmark from 'benchmark';
-import _ from 'lodash';
-
-const { Suite } = benchmark.runInContext({ _ });
-
-function runSuite (local, npm, dedupe, npmDedupe, fixture, log) {
-	const suite = new Suite();
-
-	suite.add(`local#${fixture.description}`, () => {
-		local(...fixture.args);
-	});
-
-	suite.add(`  npm#${fixture.description}`, () => {
-		npm(...fixture.args);
-	});
-
-	suite.add(`local/dedupe#${fixture.description}`, () => {
-		dedupe(...fixture.args);
-	});
-
-	suite.add(`  npm/dedupe#${fixture.description}`, () => {
-		npmDedupe(...fixture.args);
-	});
-
-	suite.on('cycle', (event) => {
-		log(`* ${event.target}`);
-	});
-
-	suite.on('complete', () => {
-		log(`\n> Fastest is ${(suite.filter('fastest').map(result => result.name).join(' | ')).replace(/\s+/, ' ')}\n`);
-	});
-
-	suite.on('error', (event) => {
-		log(event.target.error.message);
-		throw event.target.error;
-	});
-
-	suite.run();
-}
-
-export default runSuite;
diff --git a/package-lock.json b/package-lock.json
index 569476d..b236e37 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,12 +22,11 @@
         "@rollup/plugin-commonjs": "^25.0.7",
         "@rollup/plugin-json": "^6.1.0",
         "@rollup/plugin-node-resolve": "^15.2.3",
-        "benchmark": "^2.1.4",
         "classnames-local": "file:../",
         "classnames-npm": "npm:classnames@*",
         "http-server": "^14.1.1",
-        "lodash": "^4.17.21",
-        "rollup": "^4.9.1"
+        "rollup": "^4.9.1",
+        "tinybench": "^2.5.1"
       }
     },
     "node_modules/@babel/code-frame": {
@@ -643,16 +642,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/benchmark": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz",
-      "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==",
-      "dev": true,
-      "dependencies": {
-        "lodash": "^4.17.4",
-        "platform": "^1.3.3"
-      }
-    },
     "node_modules/brace-expansion": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -1808,12 +1797,6 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
-    "node_modules/platform": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
-      "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
-      "dev": true
-    },
     "node_modules/plur": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz",
@@ -2272,6 +2255,12 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/tinybench": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz",
+      "integrity": "sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==",
+      "dev": true
+    },
     "node_modules/to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",