docs: async function measure(test, bench) {
    let {
      delay,
      minTime,
      minSamples,
      minWarmups,
      onCycle,
      onSample,
    } = bench.config
    let { name, run } = test
  
    delay *= 1e3
    minTime *= 1e3
  
    let samples = []
    let cycle = {
      name, // test name
      hz: null, // samples per second
      size: null, // number of samples
      time: null, // elapsed time (including delays)
      stats: null,
    }
  
    let n = 0
    let t = process.hrtime()
    let warmups = -1
  
    // synchronous test
    if (run.length == 0) {
      let start
      while (true) {
        bench.before.forEach(call)
        if (test.before) test.before()
  
        start = process.hrtime()
        run()
        let sample = clock(start)
  
        if (test.after) test.after()
        bench.after.forEach(call)
  
        if (warmups == -1) {
          warmups = Math.max(minWarmups, sample > 100 ? 1 : sample > 10 ? 5 : 50)
        }
        if (warmups > 0) {
          warmups--
        } else {
          samples[n++] = sample
          onSample(samples[n - 1], cycle)
  
          if (minTime <= clock(t) && minSamples <= n) {
            break // all done!
          }
        }
  
        // wait then repeat
        await wait(delay)
      }
    }
  
    // asynchronous test
    else {
      let start
      const next = function() {
        bench.before.forEach(call)
        if (test.before) test.before()
  
        start = process.hrtime()
        run(done)
      }
  
      // called by the test function for every sample
      const done = function() {
        let sample = clock(start)
  
        if (test.after) test.after()
        bench.after.forEach(call)
  
        if (warmups == -1) {
          warmups = Math.max(minWarmups, sample > 100 ? 1 : sample > 10 ? 5 : 50)
        }
        if (warmups > 0) {
          warmups--
        } else {
          samples[n++] = sample
          onSample(samples[n - 1], cycle)
  
          if (minTime <= clock(t) && minSamples <= n) {
            return cycle.done() // all done!
          }
        }
  
        // wait then repeat
        wait(delay).then(next)
      }
  
      defer(cycle) // wrap cycle with a promise
      next() // get the first sample
  
      // wait for samples
      await cycle.promise
    }
  
    const time = clock(t)
    const stats = analyze(samples)
    cycle.hz = 1000 / stats.mean
    cycle.size = n
    cycle.time = time
    cycle.stats = stats
  
    onCycle(cycle, bench.config)
  }