fix: replace plimit with own promises limiter implementation to plug … · tinylibs/tinybench@6d93a1e

1-

import pLimit from 'p-limit'

2-31

import type {

42

AddEventListenerOptionsArgument,

53

BenchEvents,

@@ -26,7 +24,7 @@ import {

2624

defaultConvertTaskResultForConsoleTable,

2725

invariant,

2826

type JSRuntime,

29-

now,

27+

performanceNow,

3028

runtime,

3129

runtimeVersion,

3230

} from './utils'

@@ -109,10 +107,13 @@ export class Bench extends EventTarget {

109107

this.name = name

110108

this.runtime = runtime

111109

this.runtimeVersion = runtimeVersion

110+

this.concurrency = restOptions.concurrency ?? null

111+

this.threshold = restOptions.threshold ?? Infinity

112+112113

this.opts = {

113114

...{

114115

iterations: defaultMinimumIterations,

115-

now,

116+

now: performanceNow,

116117

setup: emptyFunction,

117118

teardown: emptyFunction,

118119

throws: false,

@@ -122,6 +123,8 @@ export class Bench extends EventTarget {

122123

warmupTime: defaultMinimumWarmupTime,

123124

},

124125

...restOptions,

126+

...(restOptions.iterations !== undefined && restOptions.time === undefined && { time: 0 }),

127+

...(restOptions.warmupIterations !== undefined && restOptions.warmupTime === undefined && { warmupTime: 0 }),

125128

}

126129127130

if (this.opts.signal) {

@@ -195,15 +198,23 @@ export class Bench extends EventTarget {

195198

if (this.opts.warmup) {

196199

await this.#warmupTasks()

197200

}

198-

let values: Task[] = []

201+199202

this.dispatchEvent(new BenchEvent('start'))

203+204+

let values: Task[] = []

205+200206

if (this.concurrency === 'bench') {

201-

values = await this.#mapTasksConcurrently(task => task.run())

207+

const taskPromises = []

208+

for (const task of this.#tasks.values()) {

209+

taskPromises.push(task.run())

210+

}

211+

values = await Promise.all(taskPromises)

202212

} else {

203213

for (const task of this.#tasks.values()) {

204214

values.push(await task.run())

205215

}

206216

}

217+207218

this.dispatchEvent(new BenchEvent('complete'))

208219

return values

209220

}

@@ -240,39 +251,18 @@ export class Bench extends EventTarget {

240251

return this.tasks.map(convert)

241252

}

242253243-

/**

244-

* Applies a worker function to all registered tasks using the concurrency limit.

245-

*

246-

* Scheduling is handled via p-limit with the current threshold. The returned array preserves

247-

* the iteration order of the tasks. If any scheduled worker function rejects, the returned promise

248-

* rejects with the first error after the scheduled worker functions settle, as per Promise.all semantics.

249-

*

250-

* Notes:

251-

* - Concurrency is controlled by Bench.threshold (Infinity means unlimited).

252-

* - No measurements are performed here; measurements happen inside Task.

253-

* - Used internally by run() and warmupTasks() when concurrency === 'bench'.

254-

* @template R The resolved type produced by the worker function for each task.

255-

* @param workerFn A function invoked for each Task; it must return a Promise<R>.

256-

* @returns Promise that resolves to an array of results in the same order as task iteration.

257-

*/

258-

async #mapTasksConcurrently<R>(

259-

workerFn: (task: Task) => Promise<R>

260-

): Promise<R[]> {

261-

const limit = pLimit(Math.max(1, Math.floor(this.threshold)))

262-

const promises: Promise<R>[] = []

263-

for (const task of this.#tasks.values()) {

264-

promises.push(limit(() => workerFn(task)))

265-

}

266-

return Promise.all(promises)

267-

}

268-269254

/**

270255

* warmup the benchmark tasks.

271256

*/

272257

async #warmupTasks (): Promise<void> {

273258

this.dispatchEvent(new BenchEvent('warmup'))

259+274260

if (this.concurrency === 'bench') {

275-

await this.#mapTasksConcurrently(task => task.warmup())

261+

const taskPromises = []

262+

for (const task of this.#tasks.values()) {

263+

taskPromises.push(task.warmup())

264+

}

265+

await Promise.all(taskPromises)

276266

} else {

277267

for (const task of this.#tasks.values()) {

278268

await task.warmup()