UNPKG

iso-bench

Version:

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

111 lines (110 loc) 3.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ForkContext = void 0; const Fork_1 = require("./Fork"); class ForkContext { _test; _processors; _resolve; _benchName; _ended = false; constructor(_test, _processors, _resolve, _benchName) { this._test = _test; this._processors = _processors; this._resolve = _resolve; this._benchName = _benchName; } start() { const setup = { testIndex: this._test.index, benchName: this._benchName }; const worker = Fork_1.Fork.fork({ ["ISO_BENCH_SETUP"]: JSON.stringify(setup) }); this._listenForCompletionMessage(worker.stdio[3]); this._listenForProcessExit(worker); } _processMessage(msg) { if (!this._ended) { if (msg.error != null) { this._test.opMs = 0; this._test.error = msg.error; this._ended = true; this._resolve(); } else if (msg.done) { this._ended = true; const totalSamples = this._test.options.samplesPerSpawn * this._test.options.spawns; if (this._test.samples.length >= totalSamples) { this._resolve(); } else { const forkContext = new ForkContext(this._test, this._processors, this._resolve, this._benchName); forkContext.start(); } } else { const sample = { cycles: msg.cycles, time: msg.diff, ops: msg.cycles / msg.diff }; this._test.samples.push(sample); this._test.totalTime += msg.diff; this._test.opMs = this._test.samples.reduce((total, sample) => total + sample.ops, 0) / this._test.samples.length; for (const processor of this._processors) { processor.sample && processor.sample(this._test, sample); } } } } _listenForCompletionMessage(stream) { let size = null; stream.on("readable", () => { try { while (stream.readable) { if (this._ended) { break; } else if (size == null) { const buffer = stream.read(2); if (buffer && buffer.length === 2) { size = buffer.readUint16LE(); } else { break; } } else { const buffer = stream.read(size); if (buffer && buffer.length === size) { size = null; const message = JSON.parse(String(buffer)); this._processMessage(message); } } } } catch (e) { this._processMessage({ error: String(e) }); } }); } _listenForProcessExit(worker) { const errBuffer = []; worker.stderr.on("data", data => errBuffer.push(data)); worker.on("close", (code) => { let err = `Process ended prematurely. Exit code: ${code}`; if (errBuffer.length > 0) { err = `${err}. Error: ${Buffer.concat(errBuffer).toString()}`; } this._processMessage({ error: err }); }); } } exports.ForkContext = ForkContext;