diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41f6be4..6ed6e57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,17 +13,28 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: npm i - run: npm run unit + benchmarks: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 20 + registry-url: https://registry.npmjs.org/ + - run: npm i + - run: npm run benchmarks coverage: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: npm i - run: npm run coverage @@ -33,7 +44,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: npm i - run: npm run gitdiff:ci @@ -43,7 +54,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: npm i - run: npm run lint diff --git a/benchmarks/main.js b/benchmarks/main.js new file mode 100644 index 0000000..79e5ead --- /dev/null +++ b/benchmarks/main.js @@ -0,0 +1,72 @@ +import { Suite } from "bench-node"; +import * as nodeTools from "../src/mjs/index.js"; +import * as browserTools from "../src/mjs/browser.js"; + +const DUMMY_BUFFER = Uint8Array.from([ + 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, + 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, + 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, + 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, + 0xbe, 0xef, +]); +const DUMMY_HEX = + "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; + +// Note: only include benchmarks for functions with differing implementations for Node and Browser +const BENCHMARKS = [ + [ + `fromHex`, + (library) => () => { + library.fromHex(DUMMY_HEX); + }, + ], + [ + `toHex`, + (library) => () => { + library.toHex(DUMMY_BUFFER); + }, + ], +]; + +const LIBRARIES = [ + ["Node ", nodeTools], + ["Browser", browserTools], +]; + +function setUpSuite(suite, platform, library, funcName, func) { + suite.add(`${platform} ${funcName}`, func(library)); +} + +async function main() { + const suite = new Suite(); + for (const [funcName, func] of BENCHMARKS) { + for (const [name, library] of LIBRARIES) { + setUpSuite(suite, name, library, funcName, func); + } + } + const results = await suite.run(); + + const nodeSlower = []; + + for (let i = 0; i < results.length; i += 2) { + const nodeResult = results[i]; + const browserResult = results[i + 1]; + if (nodeResult.opsSec < browserResult.opsSec) { + nodeSlower.push(BENCHMARKS[i / 2][0]); + } + } + if (nodeSlower.length > 0) { + throw new Error( + `\n*** Node was slower in the following:\n *** ${nodeSlower.join( + "\n *** " + )}` + ); + } +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/package.json b/package.json index 241b102..5cb6b97 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,11 @@ "types": "src/cjs/index.d.ts", "type": "module", "scripts": { - "build": "npm run clean && npm run build-ts && npm run convert-cjs && rm -f ./src/cjs/browser.d.ts", + "benchmarks": "node benchmarks/main.js", + "build": "npm run clean && npm run build-ts && npm run convert-cjs", "build-ts": "tsc -p tsconfig.json && tsc -p tsconfig-cjs.json", "clean": "rm -rf ./src/* && rm -rf ./coverage && rm -f ./package-lock.json", - "convert-cjs": "for f in ./src/cjs/*.js; do mv -- \"$f\" \"${f%.js}.cjs\"; done", + "convert-cjs": "for f in ./src/cjs/*.js; do sed -i 's/\\.js\"/.cjs\"/g' \"$f\"; mv -- \"$f\" \"${f%.js}.cjs\"; done", "coverage": "npm run unit -- --coverage", "eslint": "eslint ts_src/*.ts", "format": "npm run eslint -- --fix", @@ -50,6 +51,7 @@ "@types/node": "16.11.1", "@typescript-eslint/eslint-plugin": "5.0.0", "@typescript-eslint/parser": "5.0.0", + "bench-node": "0.0.1-beta.0", "eslint": "8.0.1", "eslint-config-prettier": "8.3.0", "eslint-plugin-prettier": "4.0.0", diff --git a/src/cjs/browser.d.ts b/src/cjs/browser.d.ts new file mode 100644 index 0000000..2a1717a --- /dev/null +++ b/src/cjs/browser.d.ts @@ -0,0 +1,5 @@ +export declare function toUtf8(bytes: Uint8Array): string; +export declare function toHex(bytes: Uint8Array): string; +export declare function fromHex(hexString: string): Uint8Array; +export declare type CompareResult = -1 | 0 | 1; +export declare function compare(v1: Uint8Array, v2: Uint8Array): CompareResult; diff --git a/src/cjs/index.cjs b/src/cjs/index.cjs index 473f705..57c6437 100644 --- a/src/cjs/index.cjs +++ b/src/cjs/index.cjs @@ -1,10 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.compare = exports.fromHex = exports.toHex = exports.toUtf8 = void 0; -function toUtf8(bytes) { - return Buffer.from(bytes || []).toString(); -} -exports.toUtf8 = toUtf8; +exports.toUtf8 = exports.compare = exports.fromHex = exports.toHex = void 0; function toHex(bytes) { return Buffer.from(bytes || []).toString("hex"); } @@ -13,7 +9,6 @@ function fromHex(hexString) { return Uint8Array.from(Buffer.from(hexString || "", "hex")); } exports.fromHex = fromHex; -function compare(v1, v2) { - return Buffer.from(v1).compare(Buffer.from(v2)); -} -exports.compare = compare; +var browser_js_1 = require("./browser.cjs"); +Object.defineProperty(exports, "compare", { enumerable: true, get: function () { return browser_js_1.compare; } }); +Object.defineProperty(exports, "toUtf8", { enumerable: true, get: function () { return browser_js_1.toUtf8; } }); diff --git a/src/cjs/index.d.ts b/src/cjs/index.d.ts index 2a1717a..17b5a34 100644 --- a/src/cjs/index.d.ts +++ b/src/cjs/index.d.ts @@ -1,5 +1,3 @@ -export declare function toUtf8(bytes: Uint8Array): string; export declare function toHex(bytes: Uint8Array): string; export declare function fromHex(hexString: string): Uint8Array; -export declare type CompareResult = -1 | 0 | 1; -export declare function compare(v1: Uint8Array, v2: Uint8Array): CompareResult; +export { compare, CompareResult, toUtf8 } from './browser.js'; diff --git a/src/mjs/index.js b/src/mjs/index.js index 8d35bf4..7baa782 100644 --- a/src/mjs/index.js +++ b/src/mjs/index.js @@ -1,12 +1,7 @@ -export function toUtf8(bytes) { - return Buffer.from(bytes || []).toString(); -} export function toHex(bytes) { return Buffer.from(bytes || []).toString("hex"); } export function fromHex(hexString) { return Uint8Array.from(Buffer.from(hexString || "", "hex")); } -export function compare(v1, v2) { - return Buffer.from(v1).compare(Buffer.from(v2)); -} +export { compare, toUtf8 } from './browser.js'; diff --git a/ts_src/index.ts b/ts_src/index.ts index deb373b..154e198 100644 --- a/ts_src/index.ts +++ b/ts_src/index.ts @@ -1,7 +1,3 @@ -export function toUtf8(bytes: Uint8Array): string { - return Buffer.from(bytes || []).toString(); -} - export function toHex(bytes: Uint8Array): string { return Buffer.from(bytes || []).toString("hex"); } @@ -10,7 +6,4 @@ export function fromHex(hexString: string): Uint8Array { return Uint8Array.from(Buffer.from(hexString || "", "hex")); } -export type CompareResult = -1 | 0 | 1; -export function compare(v1: Uint8Array, v2: Uint8Array): CompareResult { - return Buffer.from(v1).compare(Buffer.from(v2)) as CompareResult; -} +export { compare, CompareResult, toUtf8 } from './browser.js';