diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore index 07e6e47..ad08405 100644 --- a/benchmarks/.gitignore +++ b/benchmarks/.gitignore @@ -1 +1,2 @@ /node_modules +/results.csv diff --git a/benchmarks/index.html b/benchmarks/index.html index 5bffce6..8eb8a64 100644 --- a/benchmarks/index.html +++ b/benchmarks/index.html @@ -1,97 +1,40 @@ - - - -
+ + + diff --git a/benchmarks/index.mjs b/benchmarks/index.mjs index ec1d11a..e50d10a 100644 --- a/benchmarks/index.mjs +++ b/benchmarks/index.mjs @@ -1,46 +1,73 @@ -import Benchmark from 'benchmark'; -import { readdirSync, readFileSync } from 'fs'; -import prettyBytes from 'pretty-bytes'; -import { fileSync as brotliSize } from 'brotli-size'; -import { createRequire } from 'module'; -import { inspect } from 'util'; - -const { Suite } = Benchmark; -const require = createRequire(import.meta.url); +const { Suite } = globalThis.Benchmark ?? (await import('benchmark')).default; let suiteOps = { parse: {}, serialize: {} }; -const libs = readdirSync('pkg').map(dir => ({ - name: dir, - impl: require(`./pkg/${dir}`) -})); +const libs = await Promise.all( + ['serde-wasm-bindgen', 'serde-json', 'serde-wasm-bindgen-reftypes'] + .map(async dir => { + try { + const impl = await import(`./pkg/${dir}/serde_wasm_bindgen_benches.js`); + await impl.default(); // Init Wasm + return { name: dir, impl }; + } catch (err) { + console.warn(err); + return null; + } + }) + .filter(Boolean) +); + +let readFile, + filter; + +const isNode = typeof process !== 'undefined'; + +if (isNode) { + const prettyBytes = (await import('pretty-bytes')).default; + const brotliSize = await import('brotli-size'); + + console.log('=== Sizes ==='); + for (let { name } of libs) { + const [js, wasm] = [ + 'serde_wasm_bindgen_benches.js', + 'serde_wasm_bindgen_benches_bg.wasm' + ].map(file => prettyBytes(brotliSize.fileSync(`pkg/${name}/${file}`))); + + console.log(`${name}: JS = ${js}, Wasm = ${wasm}`); + } + console.log(); -console.log('=== Sizes ==='); -for (let { name } of libs) { - const [js, wasm] = [ - 'serde_wasm_bindgen_benches.js', - 'serde_wasm_bindgen_benches_bg.wasm' - ].map(file => prettyBytes(brotliSize(`pkg/${name}/${file}`))); + const readFileImpl = (await import('fs/promises')).readFile; + readFile = name => readFileImpl(name, 'utf8'); - console.log(`${name}: JS = ${js}, Wasm = ${wasm}`); + filter = process.argv[2]; +} else { + readFile = name => + fetch(name).then(res => { + if (!res.ok) { + throw new Error(`Failed to fetch ${name}`); + } + return res.text(); + }); + + filter = new URLSearchParams(location.search).get('filter'); } -console.log(); -function loadData(name) { - return JSON.parse(readFileSync(`./data/${name}.json`, 'utf8')); +filter = new RegExp(filter ?? '(?:)', 'i'); + +async function loadData(name) { + return JSON.parse(await readFile(`./data/${name}.json`, 'utf8')); } const datasets = { - Canada: loadData('canada'), - CitmCatalog: loadData('citm_catalog'), - Twitter: loadData('twitter') + Canada: await loadData('canada'), + CitmCatalog: await loadData('citm_catalog'), + Twitter: await loadData('twitter') }; -let filter = new RegExp(process.argv[2] || '(?:)'); - for (let { name: libName, impl } of libs) { for (let [dataName, json] of Object.entries(datasets)) { let { parse } = impl[dataName]; @@ -68,15 +95,35 @@ for (let { name: libName, impl } of libs) { console.log('=== Benchmarks ==='); +let csv = ''; + for (let [op, suites] of Object.entries(suiteOps)) { console.group(op); for (let suite of Object.values(suites)) { console.group(suite.name); - suite - .on('error', event => console.error(event.target.error)) - .on('cycle', event => console.log(event.target.toString())) - .run(); + await new Promise((resolve, reject) => { + suite + .on('error', event => reject(event.target.error)) + .on('cycle', event => { + console.log(event.target.toString()); + csv += `${op},${suite.name},${event.target.name},${event.target.hz}\n`; + }) + .on('complete', resolve) + .run({ + async: true + }); + }); console.groupEnd(); } console.groupEnd(); } + +if (isNode) { + (await import('fs')).writeFileSync('results.csv', csv); +} else { + let csvLink = document.createElement('a'); + csvLink.href = URL.createObjectURL(new Blob([csv], { type: 'text/csv' })); + csvLink.download = 'results.csv'; + csvLink.textContent = 'Download CSV'; + document.body.append('Done! ', csvLink); +} diff --git a/benchmarks/package.json b/benchmarks/package.json index 95bc87b..9f16f40 100644 --- a/benchmarks/package.json +++ b/benchmarks/package.json @@ -9,10 +9,10 @@ "pretty-bytes": "^6.0.0" }, "scripts": { - "build:swb": "wasm-pack build -t nodejs --out-dir pkg/serde-wasm-bindgen -- --features serde-wasm-bindgen", - "build:swb-reftypes": "cross-env RUSTFLAGS=\"-C target-feature=+reference-types\" WASM_BINDGEN_EXTERNREF=1 wasm-pack build -t nodejs --out-dir pkg/serde-wasm-bindgen-reftypes -- --features serde-wasm-bindgen", - "build:json": "wasm-pack build -t nodejs --out-dir pkg/serde-json -- --features serde-json", - "build:msgpack": "wasm-pack build -t nodejs --out-dir pkg/msgpack -- --features msgpack", + "build:swb": "wasm-pack build -t web --out-dir pkg/serde-wasm-bindgen -- --features serde-wasm-bindgen", + "build:swb-reftypes": "cross-env RUSTFLAGS=\"-C target-feature=+reference-types\" WASM_BINDGEN_EXTERNREF=1 wasm-pack build -t web --out-dir pkg/serde-wasm-bindgen-reftypes -- --features serde-wasm-bindgen", + "build:json": "wasm-pack build -t web --out-dir pkg/serde-json -- --features serde-json", + "build:msgpack": "wasm-pack build -t web --out-dir pkg/msgpack -- --features msgpack", "build": "npm run build:swb && npm run build:swb-reftypes && npm run build:json", "test": "node index.mjs" }