diff --git a/package-lock.json b/package-lock.json index 232941545d..3a63fcf1b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,6 @@ "@typescript-eslint/parser": "7.16.1", "assert": "2.1.0", "babel-loader": "9.2.1", - "benchmark": "2.1.4", "c8": "10.1.2", "codecov": "3.8.3", "core-js": "3.39.0", @@ -73,7 +72,6 @@ "ndarray-ops": "1.2.2", "ndarray-pack": "1.2.1", "numericjs": "1.2.6", - "pad-right": "0.2.2", "prettier": "3.3.3", "process": "0.11.10", "sinon": "19.0.2", @@ -3780,17 +3778,6 @@ "tweetnacl": "^0.14.3" } }, - "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, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.4", - "platform": "^1.3.3" - } - }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -10551,19 +10538,6 @@ "dev": true, "license": "BlueOak-1.0.0" }, - "node_modules/pad-right": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", - "integrity": "sha512-4cy8M95ioIGolCoMmm2cMntGR1lPLEbOMzOKu8bzjuJP6JpzEMQcDHmh7hHLYGgob+nKe1YHFMaG4V59HQa89g==", - "dev": true, - "license": "MIT", - "dependencies": { - "repeat-string": "^1.5.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10858,13 +10832,6 @@ "node": ">=4" } }, - "node_modules/platform": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", - "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", - "dev": true, - "license": "MIT" - }, "node_modules/plugin-error": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", @@ -11253,16 +11220,6 @@ "dev": true, "license": "ISC" }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/replace-ext": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", diff --git a/package.json b/package.json index ee336f1902..d215be74a3 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,6 @@ "@typescript-eslint/parser": "7.16.1", "assert": "2.1.0", "babel-loader": "9.2.1", - "benchmark": "2.1.4", "c8": "10.1.2", "codecov": "3.8.3", "core-js": "3.39.0", @@ -86,7 +85,6 @@ "ndarray-ops": "1.2.2", "ndarray-pack": "1.2.1", "numericjs": "1.2.6", - "pad-right": "0.2.2", "prettier": "3.3.3", "process": "0.11.10", "sinon": "19.0.2", diff --git a/test/benchmark/algebra.js b/test/benchmark/algebra.js index 660cd03101..5b2f48751b 100644 --- a/test/benchmark/algebra.js +++ b/test/benchmark/algebra.js @@ -1,12 +1,8 @@ // test performance of the expression parser in node.js -import Benchmark from 'benchmark' -import padRight from 'pad-right' -import { simplify, derivative } from '../../lib/esm/index.js' - -function pad (text) { - return padRight(text, 40, ' ') -} +import { Bench } from 'tinybench' +import { derivative, simplify } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' const simplifyExpr = '2 * 1 * x ^ (2 - 1)' const derivativeExpr = '2x^2 + log(3x) + 2x + 3' @@ -18,19 +14,15 @@ console.log(' ' + derivative(derivativeExpr, 'x')) const results = [] -const suite = new Benchmark.Suite() -suite - .add(pad('algebra simplify '), function () { +const bench = new Bench({ time: 100, iterations: 100 }) + .add('algebra simplify ', function () { const res = simplify(simplifyExpr) results.push(res) }) - .add(pad('algebra derivative'), function () { + .add('algebra derivative', function () { const res = derivative(derivativeExpr, 'x') results.push(res) }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - }) - .run() + +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() diff --git a/test/benchmark/derivative.js b/test/benchmark/derivative.js index 6a8a3726bd..fc5d6619bc 100644 --- a/test/benchmark/derivative.js +++ b/test/benchmark/derivative.js @@ -1,7 +1,8 @@ // test performance of derivative -import Benchmark from 'benchmark' +import { Bench } from 'tinybench' import { derivative, parse } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' let expr = parse('0') for (let i = 1; i <= 5; i++) { @@ -12,10 +13,7 @@ for (let i = 1; i <= 5; i++) { const results = [] -Benchmark.options.minSamples = 100 - -const suite = new Benchmark.Suite() -suite +const bench = new Bench({ time: 100, iterations: 100 }) .add('ddf', function () { const res = derivative(derivative(expr, parse('x'), { simplify: false }), parse('x'), { simplify: false }) results.splice(0, 1, res) @@ -24,9 +22,6 @@ suite const res = derivative(expr, parse('x'), { simplify: false }) results.splice(0, 1, res) }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - }) - .run() + +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() diff --git a/test/benchmark/expression_parser.js b/test/benchmark/expression_parser.js index bc56930db1..222341f98a 100644 --- a/test/benchmark/expression_parser.js +++ b/test/benchmark/expression_parser.js @@ -3,22 +3,13 @@ // browserify benchmark/expression_parser.js -o ./benchmark_expression_parser.js import assert from 'node:assert' -import Benchmark from 'benchmark' -import padRight from 'pad-right' -import { create, all } from '../../lib/esm/index.js' +import { Bench } from 'tinybench' +import { all, create } from '../../lib/esm/index.js' import { getSafeProperty } from '../../lib/esm/utils/customs.js' +import { formatTaskResult } from './utils/formatTaskResult.js' const math = create(all) -// expose on window when using bundled in a browser -if (typeof window !== 'undefined') { - window.Benchmark = Benchmark -} - -function pad (text) { - return padRight(text, 40, ' ') -} - const expr = '2 + 3 * sin(pi / 4) - 4x' const scope = new Map([ ['x', 2] @@ -49,40 +40,34 @@ assertApproxEqual(compiledPlainJs.evaluate(scope), correctResult, 1e-7) let total = 0 const nodes = [] -const suite = new Benchmark.Suite() -suite - .add(pad('(plain js) evaluate'), function () { +const bench = new Bench({ time: 100, iterations: 100 }) + .add('(plain js) evaluate', function () { total += compiledPlainJs.evaluate(scope) }) - .add(pad('(mathjs) evaluate'), function () { + .add('(mathjs) evaluate', function () { total += compiled.evaluate(scope) }) - .add(pad('(mathjs) parse, compile, evaluate'), function () { + .add('(mathjs) parse, compile, evaluate', function () { total += math.parse(expr).compile().evaluate(scope) }) - .add(pad('(mathjs) parse, compile'), function () { + .add('(mathjs) parse, compile', function () { const node = math.parse(expr).compile() nodes.push(node) }) - .add(pad('(mathjs) parse'), function () { + .add('(mathjs) parse', function () { const node = math.parse(expr) nodes.push(node) }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - // we count at total to prevent the browsers from not executing - // the benchmarks ("dead code") when the results would not be used. - if (total > 1e6) { - console.log('') - } else { - console.log('') - } - }) - .run() +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() + +// we count at total to prevent the browsers from not executing +// the benchmarks ("dead code") when the results would not be used. +if (total > 1e6) { + console.log('') +} function assertApproxEqual (actual, expected, tolerance) { const diff = Math.abs(expected - actual) diff --git a/test/benchmark/factorial.js b/test/benchmark/factorial.js index e5ee411189..19437d6d80 100644 --- a/test/benchmark/factorial.js +++ b/test/benchmark/factorial.js @@ -1,10 +1,6 @@ -import Benchmark from 'benchmark' -import padRight from 'pad-right' import BigNumber from 'decimal.js' - -function pad (text) { - return padRight(text, 40, ' ') -} +import { Bench } from 'tinybench' +import { formatTaskResult } from './utils/formatTaskResult.js' const results = [] @@ -45,55 +41,51 @@ function betterFactorial (n) { return prod } -const suite = new Benchmark.Suite() -suite - .add(pad('bigFactorial for small numbers'), function () { +const bench = new Bench({ time: 100, iterations: 100 }) + .add('bigFactorial for small numbers', function () { const res = bigFactorial(new BigNumber(8)) results.push(res) }) - .add(pad('new bigFactorial for small numbers'), function () { + .add('new bigFactorial for small numbers', function () { const res = betterFactorial(new BigNumber(8)) results.push(res) }) - .add(pad('bigFactorial for small numbers 2'), function () { + .add('bigFactorial for small numbers 2', function () { const res = bigFactorial(new BigNumber(20)) results.push(res) }) - .add(pad('new bigFactorial for small numbers 2'), function () { + .add('new bigFactorial for small numbers 2', function () { const res = betterFactorial(new BigNumber(20)) results.push(res) }) - .add(pad('bigFactorial for big numbers'), function () { + .add('bigFactorial for big numbers', function () { const res = bigFactorial(new BigNumber(600)) results.push(res) }) - .add(pad('new bigFactorial for big numbers'), function () { + .add('new bigFactorial for big numbers', function () { const res = betterFactorial(new BigNumber(600)) results.push(res) }) - .add(pad('bigFactorial for HUGE numbers'), function () { + .add('bigFactorial for HUGE numbers', function () { const res = bigFactorial(new BigNumber(1500)) results.push(res) }) - .add(pad('new bigFactorial for HUGE numbers'), function () { + .add('new bigFactorial for HUGE numbers', function () { const res = betterFactorial(new BigNumber(1500)) results.push(res) }) - .add(pad('bigFactorial for "HUGER" numbers'), function () { + .add('bigFactorial for "HUGER" numbers', function () { const res = bigFactorial(new BigNumber(10000)) results.push(res) }) - .add(pad('new bigFactorial for "HUGER" numbers'), function () { + .add('new bigFactorial for "HUGER" numbers', function () { const res = betterFactorial(new BigNumber(10000)) results.push(res) }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - }) - .run() + +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() diff --git a/test/benchmark/forEach.js b/test/benchmark/forEach.js index 7f3f3da510..555f4b12ae 100644 --- a/test/benchmark/forEach.js +++ b/test/benchmark/forEach.js @@ -1,6 +1,6 @@ -import Benchmark from 'benchmark' -import padRight from 'pad-right' -import { ones, abs, DenseMatrix, map, forEach, random, round } from '../../lib/esm/index.js' +import { Bench } from 'tinybench' +import { abs, DenseMatrix, forEach, map, ones, random, round } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' const genericMatrix = map(ones(10, 10, 'dense'), _ => round(random(-5, 5), 2)) const numberMatrix = new DenseMatrix(genericMatrix, 'number') @@ -9,47 +9,40 @@ const array = genericMatrix.toArray() // console.log('data', array) // console.log('abs(data)', abs(array))npm run -new Benchmark.Suite() - .add(pad('abs(genericMatrix)'), () => { +const bench = new Bench({ time: 100, iterations: 100 }) + .add('abs(genericMatrix)', () => { abs(genericMatrix) }) - .add(pad('abs(array)'), () => { + .add('abs(array)', () => { abs(array) }) - .add(pad('abs(numberMatrix)'), () => { + .add('abs(numberMatrix)', () => { abs(numberMatrix) }) - .add(pad('genericMatrix.forEach(abs)'), () => { + .add('genericMatrix.forEach(abs)', () => { genericMatrix.forEach(abs) }) - .add(pad('numberMatrix.forEach(abs)'), () => { + .add('numberMatrix.forEach(abs)', () => { numberMatrix.forEach(abs) }) - .add(pad('forEach(genericMatrix, abs)'), () => { + .add('forEach(genericMatrix, abs)', () => { forEach(genericMatrix, abs) }) - .add(pad('forEach(numberMatrix, abs)'), () => { + .add('forEach(numberMatrix, abs)', () => { forEach(numberMatrix, abs) }) - .add(pad('forEach(array, abs)'), () => { + .add('forEach(array, abs)', () => { forEach(array, abs) }) - .add(pad('forEach(array, abs.signatures.number)'), () => { + .add('forEach(array, abs.signatures.number)', () => { forEach(array, abs.signatures.number) }) - .add(pad('genericMatrix.forEach(abs.signatures.number)'), () => { + .add('genericMatrix.forEach(abs.signatures.number)', () => { genericMatrix.forEach(abs.signatures.number) }) - .add(pad('numberMatrix.forEach(abs.signatures.number)'), () => { + .add('numberMatrix.forEach(abs.signatures.number)', () => { numberMatrix.forEach(abs.signatures.number) }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - }) - .run() -function pad (text) { - return padRight(text, 45, ' ') -} +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() diff --git a/test/benchmark/load.js b/test/benchmark/load.js index 5ccb12909c..8d4e6811a4 100644 --- a/test/benchmark/load.js +++ b/test/benchmark/load.js @@ -1,38 +1,30 @@ // test performance of loading a new mathjs instance import assert from 'node:assert' -import Benchmark from 'benchmark' -import padRight from 'pad-right' -import { create, all } from '../../lib/esm/index.js' +import { Bench } from 'tinybench' +import { all, create } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' const timeLabel = 'import, parse, and load time' console.time(timeLabel) const math = create(all) console.timeEnd(timeLabel) -function pad (text) { - return padRight(text, 10, ' ') -} - let calls -const suite = new Benchmark.Suite() -suite - .add(pad('load lazy'), function () { +const bench = new Bench({ time: 100, iterations: 100 }) + .add('load lazy', function () { // load all functions lazily into a new instance const instance = math.create() assert('add' in instance) }) - .add(pad('load all'), function () { + .add('load all', function () { const instance = math.create() // force to load all lazy functions const everything = Object.values(instance) assert(everything.find(fn => fn.name === 'add')) calls = instance.typed.createCount }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - console.log(`Load all created ${calls} typed functions.`) - }) - .run() + +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() +console.log(`Created ${calls} typed functions.`) diff --git a/test/benchmark/map.js b/test/benchmark/map.js index 05b0ea3986..974265af84 100644 --- a/test/benchmark/map.js +++ b/test/benchmark/map.js @@ -1,6 +1,6 @@ -import Benchmark from 'benchmark' -import padRight from 'pad-right' -import { ones, abs, DenseMatrix, map, random, round } from '../../lib/esm/index.js' +import { Bench } from 'tinybench' +import { abs, DenseMatrix, map, ones, random, round } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' const genericMatrix = map(ones(10, 10, 'dense'), _ => round(random(-5, 5), 2)) const numberMatrix = new DenseMatrix(genericMatrix, 'number') @@ -9,47 +9,40 @@ const array = genericMatrix.toArray() // console.log('data', array) // console.log('abs(data)', abs(array))npm run -new Benchmark.Suite() - .add(pad('abs(genericMatrix)'), () => { +const bench = new Bench({ time: 100, iterations: 100 }) + .add('abs(genericMatrix)', () => { abs(genericMatrix) }) - .add(pad('abs(array)'), () => { + .add('abs(array)', () => { abs(array) }) - .add(pad('abs(numberMatrix)'), () => { + .add('abs(numberMatrix)', () => { abs(numberMatrix) }) - .add(pad('genericMatrix.map(abs)'), () => { + .add('genericMatrix.map(abs)', () => { genericMatrix.map(abs) }) - .add(pad('numberMatrix.map(abs)'), () => { + .add('numberMatrix.map(abs)', () => { numberMatrix.map(abs) }) - .add(pad('map(genericMatrix, abs)'), () => { + .add('map(genericMatrix, abs)', () => { map(genericMatrix, abs) }) - .add(pad('map(numberMatrix, abs)'), () => { + .add('map(numberMatrix, abs)', () => { map(numberMatrix, abs) }) - .add(pad('map(array, abs)'), () => { + .add('map(array, abs)', () => { map(array, abs) }) - .add(pad('map(array, abs.signatures.number)'), () => { + .add('map(array, abs.signatures.number)', () => { map(array, abs.signatures.number) }) - .add(pad('genericMatrix.map(abs.signatures.number)'), () => { + .add('genericMatrix.map(abs.signatures.number)', () => { genericMatrix.map(abs.signatures.number) }) - .add(pad('numberMatrix.map(abs.signatures.number)'), () => { + .add('numberMatrix.map(abs.signatures.number)', () => { numberMatrix.map(abs.signatures.number) }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - }) - .run() -function pad (text) { - return padRight(text, 42, ' ') -} +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() diff --git a/test/benchmark/matrix_operations.js b/test/benchmark/matrix_operations.js index 79e40fc713..e0c189ab46 100644 --- a/test/benchmark/matrix_operations.js +++ b/test/benchmark/matrix_operations.js @@ -19,8 +19,9 @@ import sylvester from 'sylvester' import eig from 'eigen' import zeros from 'zeros' import { all, create } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' -const bench = new Bench({ time: 100 }) +const bench = new Bench({ time: 10, iterations: 100 }) const math = create(all) // fiedler matrix 25 x 25 @@ -115,12 +116,6 @@ const fiedler = [ bench.add('matrix operations eigen-js det(A)', function () { return A.det() }) })() + bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) await bench.run() - - console.table(bench.tasks.map(({ name, result }) => ({ - Name: name, - 'Ops/sec': Math.round(result?.hz), - 'Average Time (\u00b5s)': result?.mean * 1000, - 'Variance (\u00b5s)': result?.variance * 1000 - }))) })().catch(console.error) diff --git a/test/benchmark/prime.js b/test/benchmark/prime.js index 786f6faf0a..cf1f18981b 100644 --- a/test/benchmark/prime.js +++ b/test/benchmark/prime.js @@ -1,6 +1,7 @@ import assert from 'node:assert' -import Benchmark from 'benchmark' +import { Bench } from 'tinybench' import { isPrime } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' const primes = [2147483647, 87178291199, 4398042316799] const notPrimes = [2199023255551, 8796093022207, 140737488355327] @@ -14,7 +15,7 @@ assert(primesResults.every(result => result === true)) assert(notPrimesResults.every(result => result === false)) assert(carmichaelsResults.every(result => result === false)) -new Benchmark.Suite() +const bench = new Bench({ time: 100, iterations: 100 }) .add('primes', () => { primes.forEach(num => isPrime(num)) }) @@ -24,9 +25,6 @@ new Benchmark.Suite() .add('carmichaels', () => { carmichaels.forEach(num => isPrime(num)) }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - }) - .run() + +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() diff --git a/test/benchmark/roots.js b/test/benchmark/roots.js index 002c3d71b7..44f8ada28c 100644 --- a/test/benchmark/roots.js +++ b/test/benchmark/roots.js @@ -1,12 +1,8 @@ // test performance of the expression parser in node.js -import Benchmark from 'benchmark' -import padRight from 'pad-right' +import { Bench } from 'tinybench' import { polynomialRoot } from '../../lib/esm/index.js' - -function pad (text) { - return padRight(text, 40, ' ') -} +import { formatTaskResult } from './utils/formatTaskResult.js' const maxCoeff = 5 function countRoots () { @@ -31,15 +27,11 @@ console.log('polynomials (with coefficients <=', maxCoeff, ')') const results = [] -const suite = new Benchmark.Suite() -suite - .add(pad('count roots'), function () { +const bench = new Bench({ time: 100, iterations: 100 }) + .add('count roots', function () { const res = countRoots() results.push(res) }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - }) - .run() + +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() diff --git a/test/benchmark/scope_variables.js b/test/benchmark/scope_variables.js index f4e73811f5..11f52a9be9 100644 --- a/test/benchmark/scope_variables.js +++ b/test/benchmark/scope_variables.js @@ -1,20 +1,20 @@ // test performance of resolving scope variables in the expression parser -import Benchmark from 'benchmark' +import { Bench } from 'tinybench' import { evaluate } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' const scope = { a: 2, b: 3, c: 4 } const f = evaluate('f(x, y) = a + b + c + x + y', scope) console.log('f(5, 6) = ' + f(5, 6)) -const suite = new Benchmark.Suite() +const bench = new Bench({ time: 100, iterations: 100 }) let res = 0 -suite +bench .add('evaluate f(x, y)', function () { res = f(-res, res) // make it dynamic, using res as argument }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .run() + +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() diff --git a/test/benchmark/unit_parser.js b/test/benchmark/unit_parser.js index 92d8b77970..ffa3f1344a 100644 --- a/test/benchmark/unit_parser.js +++ b/test/benchmark/unit_parser.js @@ -2,13 +2,9 @@ // browserify benchmark/unit_parser.js -o ./benchmark_unit_parser.js -import Benchmark from 'benchmark' -import { Unit, evaluate } from '../../lib/esm/index.js' - -// expose on window when using bundled in a browser -if (typeof window !== 'undefined') { - window.Benchmark = Benchmark -} +import { Bench } from 'tinybench' +import { evaluate, Unit } from '../../lib/esm/index.js' +import { formatTaskResult } from './utils/formatTaskResult.js' const expr = '[1mm, 2mm, 3mm, 4mm, 5mm, 6mm, 7mm, 8mm, 9mm, 10mm]' @@ -17,24 +13,19 @@ console.log('evaluate expression:', expr) let total = 0 -const suite = new Benchmark.Suite() -suite +const bench = new Bench({ time: 100, iterations: 100 }) .add('Unit.parse', function () { total += Unit.parse('mm').dimensions[0] }) .add('evaluate', function () { total += evaluate(expr).size()[0] }) - .on('cycle', function (event) { - console.log(String(event.target)) - }) - .on('complete', function () { - // we count at total to prevent the browsers from not executing - // the benchmarks ("dead code") when the results would not be used. - if (total > 5) { - console.log('') - } else { - console.log('') - } - }) - .run() + +bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task))) +await bench.run() + +// we count at total to prevent the browsers from not executing +// the benchmarks ("dead code") when the results would not be used. +if (total > 5) { + console.log('') +} diff --git a/test/benchmark/utils/formatTaskResult.js b/test/benchmark/utils/formatTaskResult.js new file mode 100644 index 0000000000..ad1a2c615e --- /dev/null +++ b/test/benchmark/utils/formatTaskResult.js @@ -0,0 +1,31 @@ +const durationWidth = 10 +const varianceWidth = 8 + +/** + * Format a result like "Task name 2.30 µs ±0.79%" + * @param {import('tinybench').Bench} bench + * @param {import('tinybench').Task} task + * @return {string} + */ +export function formatTaskResult (bench, task) { + const nameWidth = Math.max(...bench.tasks.map(task => task.name.length)) + 1 + + const name = task.name + const { variance, mean } = task.result.latency + + const meanStr = `${(mean * 1000).toFixed(2)} \u00b5s` + const varianceStr = `±${((variance / mean) * 100).toFixed(2)}%` + return `${padRight(name, nameWidth)} ${padLeft(meanStr, durationWidth)} ${padLeft(varianceStr, varianceWidth)}` +} + +function padRight (text, len, char = ' ') { + const add = Math.max(len - text.length, 0) + + return text + char.repeat(add) +} + +function padLeft (text, len, char = ' ') { + const add = Math.max(len - text.length, 0) + + return char.repeat(add) + text +}