diff --git a/packages/vitest/src/runtime/runners/benchmark.ts b/packages/vitest/src/runtime/runners/benchmark.ts index 86310dc58..5ac05565c 100644 --- a/packages/vitest/src/runtime/runners/benchmark.ts +++ b/packages/vitest/src/runtime/runners/benchmark.ts @@ -47,14 +47,32 @@ async function runBenchmarkSuite(suite: Suite, runner: VitestRunner) { if (benchmarkGroup.length) { const defer = createDefer() - const benchmarkMap: Record = {} suite.result = { state: 'run', startTime: start, benchmark: createBenchmarkResult(suite.name), } updateTask(suite) - benchmarkGroup.forEach((benchmark, idx) => { + + const addBenchTaskListener = (task: InstanceType, benchmark: Benchmark) => { + task.addEventListener('complete', (e) => { + const task = e.task + const taskRes = task.result! + const result = benchmark.result!.benchmark! + Object.assign(result, taskRes) + updateTask(benchmark) + }, { + once: true, + }) + task.addEventListener('error', (e) => { + const task = e.task + defer.reject(benchmark ? task.result!.error : e) + }, { + once: true, + }) + } + + benchmarkGroup.forEach((benchmark) => { const options = getBenchOptions(benchmark) const benchmarkInstance = new Bench(options) @@ -65,50 +83,32 @@ async function runBenchmarkSuite(suite: Suite, runner: VitestRunner) { startTime: start, benchmark: createBenchmarkResult(benchmark.name), } - const id = idx.toString() - benchmarkMap[id] = benchmark - const task = new Task(benchmarkInstance, id, benchmarkFn) + const task = new Task(benchmarkInstance, benchmark.name, benchmarkFn) benchmarkTasks.set(benchmark, task) + addBenchTaskListener(task, benchmark) updateTask(benchmark) }) - benchmarkGroup.forEach((benchmark) => { - const task = benchmarkTasks.get(benchmark)! - task.addEventListener('complete', (e) => { - const task = e.task - const _benchmark = benchmarkMap[task.name || ''] - if (_benchmark) { - const taskRes = task.result! - const result = _benchmark.result!.benchmark! - Object.assign(result, taskRes) - updateTask(_benchmark) - } - }) - task.addEventListener('error', (e) => { - const task = e.task - const _benchmark = benchmarkMap[task.name || ''] - defer.reject(_benchmark ? task.result!.error : e) - }) - }) - - const tasks: BenchTask[] = [] + const { setTimeout } = getSafeTimers() + const tasks: [BenchTask, Benchmark][] = [] for (const benchmark of benchmarkGroup) { const task = benchmarkTasks.get(benchmark)! await task.warmup() - const { setTimeout } = getSafeTimers() - tasks.push(await new Promise(resolve => setTimeout(async () => { - resolve(await task.run()) - }))) + tasks.push([ + await new Promise(resolve => setTimeout(async () => { + resolve(await task.run()) + })), + benchmark, + ]) } suite.result!.duration = performance.now() - start suite.result!.state = 'pass' tasks - .sort((a, b) => a.result!.mean - b.result!.mean) - .forEach((cycle, idx) => { - const benchmark = benchmarkMap[cycle.name || ''] + .sort(([taskA], [taskB]) => taskA.result!.mean - taskB.result!.mean) + .forEach(([, benchmark], idx) => { benchmark.result!.state = 'pass' if (benchmark) { const result = benchmark.result!.benchmark!