UNPKG

iso-bench

Version:

Small benchmark library focused in avoiding optimization/deoptimization pollution between tests by isolating them.

146 lines (145 loc) 4.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IsoBench = void 0; const Test_1 = require("./Test"); const Messager_1 = require("./Messager"); const WorkerSetup_1 = require("./WorkerSetup"); const processors_1 = require("./processors"); let IDs = 0; function getUniqueName(name, map) { let newName = name; while (map.has(newName)) { newName = `${name}_${IDs++}`; } return newName; } const BENCHES = new Map(); class IsoBench { name; processors = []; tests = []; currentTests = []; options; running = false; constructor(name = "IsoBench", options) { this.name = name; this.options = { ...{ parallel: 1, samplesPerSpawn: 5, spawns: 10, customCycles: null, time: 100 }, ...options }; this.name = getUniqueName(this.name, BENCHES); BENCHES.set(this.name, this); } static IfMaster(cb) { if (!WorkerSetup_1.WorkerSetup) { cb(); } } add(name, callback, setup, options) { if (this.running) { throw new Error("Can't add tests to a running bench"); } if (setup && typeof setup === "object") { options = setup; setup = null; } const filteredTestOptions = options && Object.fromEntries(Object.entries(options).filter(([_, v]) => v !== undefined)); const test = new Test_1.Test(name, this.tests.length, { ...this.options, ...filteredTestOptions }, { callback: callback, setup: typeof setup === "function" ? setup : null }); this.tests.push(test); this.currentTests.push(test); return this; } addProcessor(processorCallback) { if (WorkerSetup_1.WorkerSetup) { return this; } if (this.running) { throw new Error("Can't add processors to a running bench"); } this.processors.push(processorCallback()); return this; } consoleLog() { if (WorkerSetup_1.WorkerSetup) { return this; } return this.addProcessor(() => new processors_1.ConsoleLog()); } streamLog(streamCallback) { if (WorkerSetup_1.WorkerSetup) { return this; } return this.addProcessor(() => new processors_1.StreamLog(streamCallback())); } endGroup(name) { for (const test of this.currentTests.splice(0)) { test.setGroup(name); } return this; } async run() { if (this.running) { throw new Error("Already running"); } this.running = true; this.endGroup(""); if (WorkerSetup_1.WorkerSetup) { this._start(WorkerSetup_1.WorkerSetup); } else { if (this.processors.length === 0) { this.consoleLog(); } let i = 0; const tests = this.tests.slice(); for (const processor of this.processors) { processor.initialize && processor.initialize(this, tests); } await Promise.all(new Array(this.options.parallel).fill(0).map(async () => { while (i < tests.length) { const test = tests[i++]; for (const processor of this.processors) { processor.start && processor.start(test); } await test.fork(this.name, this.processors, this.options); for (const processor of this.processors) { processor.end && processor.end(test); } } })); for (const processor of this.processors) { processor.completed && processor.completed(tests); } } } async _start(setup) { if (this.name === setup.benchName) { try { const test = this.tests[setup.testIndex]; if (!test) { throw new Error("Test index " + setup.testIndex + " not found"); } await test.run(); await Messager_1.Messager.send({ done: true }); } catch (e) { await Messager_1.Messager.send({ error: String(e) }); } process.exit(); } } } exports.IsoBench = IsoBench;