diff --git a/README.md b/README.md index b82bd03..c783622 100644 --- a/README.md +++ b/README.md @@ -198,15 +198,15 @@ Adds a built-in [Processor](#i-processor) that outputs the result in the console --- ```typescript -bench.streamLog(stream:Stream.Writable):this; +bench.streamLog(streamCallback:() => Stream.Writable):this; ``` -Adds a built-in [Processor](#i-processor) that outputs the result in a writable stream, like a file or a socket. Returns the IsoBench instance. +Adds a built-in [Processor](#i-processor) that outputs the result in a writable stream, like a file or a socket. The writable stream should be returned inside the callback function and will be only called in the main process. Returns the IsoBench instance. --- ```typescript -bench.addProcessor(processor:Processor):this; +bench.addProcessor(processorCallback:() => Processor):this; ``` -Adds a custom [Processor](#i-processor) that must implement the [Processor](#i-processor) interface. Returns the IsoBench instance. +Adds a custom [Processor](#i-processor) that must implement the [Processor](#i-processor) interface. The callback should return a [Processor](#i-processor) instance and will be only called in the main process. Returns the IsoBench instance. --- ```typescript diff --git a/package.json b/package.json index db9a6f6..7408592 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iso-bench", - "version": "2.4.4", + "version": "2.4.5", "description": "Small benchmark library focused in avoiding optimization/deoptimization pollution between tests by isolating them.", "types": "./lib/_types/index.d.ts", "main": "./lib/", diff --git a/src/IsoBench.ts b/src/IsoBench.ts index 92e61a8..38cc8b6 100644 --- a/src/IsoBench.ts +++ b/src/IsoBench.ts @@ -54,27 +54,27 @@ export class IsoBench { this.currentTests.push(test); return this; } - addProcessor(processor:Processor) { + addProcessor(processorCallback:() => Processor) { if (WorkerSetup) { return this; } if (this.running) { throw new Error("Can't add processors to a running bench"); } - this.processors.push(processor); + this.processors.push(processorCallback()); return this; } consoleLog() { if (WorkerSetup) { return this; } - return this.addProcessor(new ConsoleLog()); + return this.addProcessor(() => new ConsoleLog()); } - streamLog(stream:STREAM.Writable) { + streamLog(streamCallback:() => STREAM.Writable) { if (WorkerSetup) { return this; } - return this.addProcessor(new StreamLog(stream)); + return this.addProcessor(() => new StreamLog(streamCallback())); } endGroup(name:string) { for (const test of this.currentTests.splice(0)) { diff --git a/src/tests/example.ts b/src/tests/example.ts index 52b5cf8..47e3fe9 100644 --- a/src/tests/example.ts +++ b/src/tests/example.ts @@ -1,18 +1,81 @@ +import FS from "fs"; + import { IsoBench } from ".."; -const dates = new Array(1000).fill(0).map(() => new Date(Math.floor(Date.now() - (Math.random() * 1000000000)))); +const buffers = new Array(1000).fill(0).map(() => Buffer.allocUnsafe(1)); +buffers.forEach(buffer => buffer[0] = Math.floor(Math.random() * 0xFF)); -const bench = new IsoBench("test"); -bench.add("iso", () => { - let res = 0; - for (const date of dates) { - res += Buffer.byteLength(date.toISOString()); - } -}); -bench.add("calc", () => { - let res = 0; - for (const date of dates) { - res += Buffer.byteLength(`${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}-${String(date.getUTCDate()).padStart(2, "0")}T${String(date.getUTCHours()).padStart(2, "0")}:${String(date.getUTCMinutes()).padStart(2, "0")}:${String(date.getUTCSeconds()).padStart(2, "0")}.${String(date.getUTCMilliseconds()).padStart(3, "0")}`); - } -}); -bench.consoleLog().run(); \ No newline at end of file +const bench = new IsoBench("MyBench"); +bench +.add("readUint8", () =>{ + for (const buffer of buffers) { + buffer.readUint8(0); + } +}) +.add("direct", () =>{ + for (const buffer of buffers) { + buffer[0]; + } +}) +.endGroup("yay...") +.add("direct", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}) +.add("readUint8", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}).endGroup("yay...2") +.add("direct", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}) +.add("readUint8", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}).endGroup("yay...3") +.add("direct", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}) +.add("readUint8", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}).endGroup("yay...4") +.add("direct", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}) +.add("readUint8", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}).endGroup("yay...5") +.add("direct", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}) +.add("readUint8", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}).endGroup("yay...6") +.add("direct", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}) +.add("readUint8", () => { + for (const buffer of buffers) { + buffer.readUint8(0); + } +}).endGroup("yay...7") +.streamLog(() => FS.createWriteStream("test.txt")).run(); \ No newline at end of file diff --git a/src/tests/general.ts b/src/tests/general.ts deleted file mode 100644 index 6d0a8ac..0000000 --- a/src/tests/general.ts +++ /dev/null @@ -1,55 +0,0 @@ -import * as UTIL from "util"; -import type * as CRYPTO_T from "crypto"; - -import { IsoBench } from ".."; -import { STRINGS } from "../STRINGS"; - -const _consoleLog = console.log; -function testLog(log:RegExp, ...logs:RegExp[]) { // Force typings at least 1 argument - logs.unshift(log); - console.log = (...args:unknown[]) => { - let str = UTIL.formatWithOptions({ colors: false }, new Array(args.length).fill("%s").join(" "), ...args.map(el => el instanceof Buffer ? UTIL.inspect(el) : el)); - let log = logs.shift()!; - if (!log.test(str)) { - throw new Error("Invalid log test: " + log + ". Received: " + str); - } else if (logs.length === 0) { - console.log = () => {}; - } - }; -} - -const SLOW_REGEXP = new RegExp(`^slow.*1\\.000x \\(${STRINGS.WORSE}\\)$`); -const FAST_REGEXP = new RegExp(`^fast.*x \\(${STRINGS.BEST}\\)$`); - -function slowfast() { - _consoleLog("Testing slow-fast result comparison"); - const bench = new IsoBench("My bench", { - time: 100, - parallel: 2 - }).add("slow", () => { - /s/.test("test this"); - }).add("fast", () => { - "test this".indexOf("s"); - }).consoleLog(); - testLog(SLOW_REGEXP, FAST_REGEXP); - return bench.run(); -} -function fastslow() { - _consoleLog("Testing fast-slow result comparison"); - const bench = new IsoBench("My bench", { - time: 100, - parallel: 2 - }).add("fast", () => { - "test this".indexOf("s"); - }).add("slow", () => { - /s/.test("test this"); - }).consoleLog(); - testLog(FAST_REGEXP, SLOW_REGEXP); - return bench.run(); -} - -(async function() { - await slowfast(); - await fastslow(); - IsoBench.IfMaster(() => _consoleLog("Tests completed")); -})(); \ No newline at end of file