1 import { strictEqual } from 'node:assert'
2 import { env } from 'node:process'
4 import Benchmark from 'benchmark'
5 import { bench, clear, group, run } from 'tatami-ng'
14 WorkerChoiceStrategies,
16 } from '../lib/index.mjs'
17 import { executeTaskFunction } from './benchmarks-utils.cjs'
19 const buildPoolifierPool = (workerType, poolType, poolSize, poolOptions) => {
23 case WorkerTypes.thread:
24 return new FixedThreadPool(
26 './benchmarks/internal/thread-worker.mjs',
29 case WorkerTypes.cluster:
30 return new FixedClusterPool(
32 './benchmarks/internal/cluster-worker.cjs',
37 case PoolTypes.dynamic:
39 case WorkerTypes.thread:
40 return new DynamicThreadPool(
41 Math.floor(poolSize / 2),
43 './benchmarks/internal/thread-worker.mjs',
46 case WorkerTypes.cluster:
47 return new DynamicClusterPool(
48 Math.floor(poolSize / 2),
50 './benchmarks/internal/cluster-worker.cjs',
58 const runPoolifierPool = async (pool, { taskExecutions, workerData }) => {
59 return await new Promise((resolve, reject) => {
61 for (let i = 1; i <= taskExecutions; i++) {
66 if (executions === taskExecutions) {
79 export const runPoolifierBenchmarkBenchmarkJs = async (
85 { taskExecutions, workerData }
87 return await new Promise((resolve, reject) => {
88 const pool = buildPoolifierPool(workerType, poolType, poolSize, poolOptions)
89 let workerChoiceStrategy
91 let workerChoiceStrategyOptions
92 if (poolOptions != null) {
96 workerChoiceStrategyOptions
99 const measurement = workerChoiceStrategyOptions?.measurement
101 `${name} with ${workerChoiceStrategy ?? pool.opts.workerChoiceStrategy}${
102 measurement != null ? `, with ${measurement}` : ''
103 } and ${enableTasksQueue ? 'with' : 'without'} tasks queue`,
105 await runPoolifierPool(pool, {
112 if (workerChoiceStrategy != null) {
113 strictEqual(pool.opts.workerChoiceStrategy, workerChoiceStrategy)
115 if (enableTasksQueue != null) {
116 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
118 if (measurement != null) {
120 pool.opts.workerChoiceStrategyOptions.measurement,
125 onComplete: event => {
126 console.info(event.target.toString())
127 if (pool.started && !pool.destroying) {
128 pool.destroy().then(resolve).catch(reject)
134 if (pool.started && !pool.destroying) {
138 return reject(event.target.error)
142 reject(event.target.error)
146 ).run({ async: true })
150 export const runPoolifierBenchmarkBenchmarkJsSuite = async (
155 { taskExecutions, workerData }
157 return await new Promise((resolve, reject) => {
158 const pool = buildPoolifierPool(workerType, poolType, poolSize)
159 const suite = new Benchmark.Suite(name, {
161 if (pool.started && !pool.destroying) {
162 pool.destroy().then(resolve).catch(reject)
168 console.info(event.target.toString())
171 if (pool.started && !pool.destroying) {
175 return reject(event.target.error)
179 reject(event.target.error)
183 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
184 for (const enableTasksQueue of [false, true]) {
185 if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
186 for (const measurement of [Measurements.runTime, Measurements.elu]) {
188 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
189 enableTasksQueue ? 'with' : 'without'
192 await runPoolifierPool(pool, {
199 pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
202 pool.enableTasksQueue(enableTasksQueue)
204 pool.opts.workerChoiceStrategy,
207 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
209 pool.opts.workerChoiceStrategyOptions.measurement,
218 `${name} with ${workerChoiceStrategy} and ${
219 enableTasksQueue ? 'with' : 'without'
222 await runPoolifierPool(pool, {
229 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
230 pool.enableTasksQueue(enableTasksQueue)
232 pool.opts.workerChoiceStrategy,
235 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
243 .on('complete', function () {
246 LIST_FORMATTER.format(this.filter('fastest').map('name'))
249 .run({ async: true })
253 export const runPoolifierBenchmarkTatamiNg = async (
258 { taskExecutions, workerData }
261 const pool = buildPoolifierPool(workerType, poolType, poolSize)
262 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
263 for (const enableTasksQueue of [false, true]) {
264 if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
265 for (const measurement of [Measurements.runTime, Measurements.elu]) {
268 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
269 enableTasksQueue ? 'with' : 'without'
272 await runPoolifierPool(pool, {
279 pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
282 pool.enableTasksQueue(enableTasksQueue)
284 pool.opts.workerChoiceStrategy,
287 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
289 pool.opts.workerChoiceStrategyOptions.measurement,
300 `${name} with ${workerChoiceStrategy} and ${
301 enableTasksQueue ? 'with' : 'without'
304 await runPoolifierPool(pool, {
311 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
312 pool.enableTasksQueue(enableTasksQueue)
314 pool.opts.workerChoiceStrategy,
317 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
326 json: env.CI != null ? 'bmf' : false
335 const LIST_FORMATTER = new Intl.ListFormat('en-US', {
340 export { executeTaskFunction }