Skip to content

Feature: add addTask method to Bench #652

Description

@ivyhjk

Motivation

Currently Bench.add() internally constructs a Task instance from (name, fn, fnOpts), leaving no room to use a Task subclass.

This change extracts that logic into a new addTask(task: Task) method that accepts an already-built Task instance. This allows creating custom Task subclasses that encapsulate specific logic (before, after, or during a benchmark run) without having to modify Bench's internal flow, improving the organization, reusability, and testability of the code that consumes the library.

This enables use cases such as validation or integrity checks before running a benchmark, custom logging or metrics, specific setup/teardown logic, or conditionally skipping a task, among others.

Changes

  • add() now delegates to the new addTask() method. add()'s behavior and signature remain unchanged — this is a non-breaking change.
  • Adds addTask(task: Task): this, which registers the given Task and throws an Error if one with the same name already exists.
/**
 * Adds a benchmark task to the task map.
 * @param name - the task name
 * @param fn - the task function
 * @param fnOpts - the task function options
 * @returns the Bench instance
 * @throws {Error} when a task with the same name already exists
 */
add (name: string, fn: Fn, fnOpts: FnOptions = {}): this {
  return this.addTask(new Task(this, name, fn, fnOpts))
}

/**
 * Adds a benchmark task to the task map.
 * @param task - the task to be added
 * @returns the Bench instance
 * @throws {Error} when a task with the same name already exists
 */
addTask (task: Task): this {
  if (!this.#tasks.has(task.name)) {
    this.#tasks.set(task.name, task)
    this.dispatchEvent(new BenchEvent('add', task))
  } else {
    throw new Error(`Task "${task.name}" already exists`)
  }

  return this
}

Example usage

import { Bench, Task } from 'tinybench';

class MyCustomTask extends Task {
  // ...
}

const bench = new Bench(/* ... */)
bench.addTask(new MyCustomTask(/* ... */))

Compatibility

Does not break the existing public API. add() keeps its current behavior.

TODO

  • Tests for addTask (duplicate name, 'add' event dispatch)
  • Update README

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions