singledispatch vs classical dispatch

Benchmark created on


Setup

const error = type => {
  throw new TypeError(`singledispatch not implemented for type ${type.constructor.name}`)
}

// Create a generic function that dispatches on the first argument.
// Returns a wrapped function that calls `defun`.
//
// Custom implementations for specific types can be registered through calling
// `.register(constructor, fun)` on the wrapped function.
//
// The default implementation is also exposed at `.default` on the wrapped
// function.
const singledispatch = (defun=error) => {
  let key = Symbol('singledispatch')

  const dispatch = (subject, ...rest) => {
    let fun = subject[key]
    if (fun) {
      return fun(subject, ...rest)
    }
    return defun(subject, ...rest)
  }
  dispatch.default = defun

  const register = (constructor, fun) => {
    constructor.prototype[key] = fun
  }
  dispatch.register = register

  return dispatch
}

class Foo {
  constructor(x) {
  	this.x = x
  }

  add(y) {
  	return this.x + y
  }
}

let add = singledispatch()
add.register(Foo, (foo, y) => foo.x + y)

const fadd = (x, y) => x + y

let foo = new Foo(2)

Test runner

Ready to run.

Testing in
TestOps/sec
Plain function
fadd(foo.x, 2)
ready
Classical dispatch
foo.add(2)
ready
Single dispatch
add(foo, 2)
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.