diff --git a/README.md b/README.md index 9790dc8..8ddd154 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ export type Hook = (task: Task, mode: "warmup" | "run") => void | Promise; ``` - `async run()`: run the added tasks that were registered using the `add` method -- `async runConcurrently(limit: number = Infinity)`: similar to the `run` method but runs concurrently rather than sequentially +- `async runConcurrently(limit: number = Infinity, mode: "bench" | "task" = "bench")`: similar to the `run` method but runs concurrently rather than sequentially. See the [Concurrency](#Concurrency) section. - `async warmup()`: warm up the benchmark tasks - `reset()`: reset each task and remove its result - `add(name: string, fn: Fn, opts?: FnOpts)`: add a benchmark task to the task map @@ -370,6 +370,24 @@ import { hrtimeNow } from 'tinybench'; ``` It may make your benchmarks slower, check #42. +## Concurrency + +- When `mode` is set to `null` (default), concurrency is disabled. +- When `mode` is set to 'task', each task's iterations run concurrently. +- When `mode` is set to 'bench', different tasks within the bench run concurrently + +```ts +// options way (recommended) +bench.threshold = 10 // The maximum number of concurrent tasks to run. Defaults to Infinity. +bench.concurrency = "task" // The concurrency mode to determine how tasks are run. +await bench.run() + +// standalone method way +await bench.runConcurrently(10, "task") // with runConcurrently, mode is set to 'bench' by default +``` + +The first way of doing concurrency also affects `bench.warmup` and makes it concurrent too. + ## Prior art - [Benchmark.js](https://github.com/bestiejs/benchmark.js) diff --git a/src/bench.ts b/src/bench.ts index 6bd0e63..7ed9d13 100644 --- a/src/bench.ts +++ b/src/bench.ts @@ -24,8 +24,18 @@ export default class Bench extends EventTarget { _todos: Map = new Map(); + /** + * Executes tasks concurrently based on the specified concurrency mode. + * + * - When `mode` is set to `null` (default), concurrency is disabled. + * - When `mode` is set to 'task', each task's iterations run concurrently. + * - When `mode` is set to 'bench', different tasks within the bench run concurrently. + */ concurrency: 'task' | 'bench' | null = null; + /** + * The maximum number of concurrent tasks to run. Defaults to Infinity. + */ threshold = Infinity; signal?: AbortSignal; @@ -81,7 +91,11 @@ export default class Bench extends EventTarget { * {@link add} method. * Note: This method does not do any warmup. Call {@link warmup} for that. */ - async run() { + async run(): Promise { + if (this.concurrency === 'bench') { + // TODO: in the next major, we should remove runConcurrently + return this.runConcurrently(this.threshold, this.concurrency); + } this.dispatchEvent(createBenchEvent('start')); const values: Task[] = []; for (const task of [...this._tasks.values()]) { @@ -92,15 +106,9 @@ export default class Bench extends EventTarget { } /** - * Executes tasks concurrently based on the specified concurrency mode. - * - * - When `mode` is set to 'task', each task's iterations run concurrently. - * - When `mode` is set to 'bench', different tasks within the bench run concurrently. - * - * @param threshold - The maximum number of concurrent tasks to run. Defaults to Infinity. - * @param mode - The concurrency mode to determine how tasks are run. Defaults to 'bench'. - */ - async runConcurrently(threshold = Infinity, mode: NonNullable = 'bench') { + * See Bench.{@link concurrency} + */ + async runConcurrently(threshold = Infinity, mode: NonNullable = 'bench'): Promise { this.threshold = threshold; this.concurrency = mode;