1 const { randomInt } = require('node:crypto')
2 const { strictEqual } = require('node:assert')
10 const Benchmark = require('benchmark')
18 WorkerChoiceStrategies,
20 } = require('../lib/index.cjs')
21 const { TaskFunctions } = require('./benchmarks-types.cjs')
23 const buildPoolifierPool = (workerType, poolType, poolSize, poolOptions) => {
27 case WorkerTypes.thread:
28 return new FixedThreadPool(
30 './benchmarks/internal/thread-worker.mjs',
33 case WorkerTypes.cluster:
34 return new FixedClusterPool(
36 './benchmarks/internal/cluster-worker.cjs',
41 case PoolTypes.dynamic:
43 case WorkerTypes.thread:
44 return new DynamicThreadPool(
45 Math.floor(poolSize / 2),
47 './benchmarks/internal/thread-worker.mjs',
50 case WorkerTypes.cluster:
51 return new DynamicClusterPool(
52 Math.floor(poolSize / 2),
54 './benchmarks/internal/cluster-worker.cjs',
62 const runPoolifierPool = async (pool, { taskExecutions, workerData }) => {
63 return await new Promise((resolve, reject) => {
65 for (let i = 1; i <= taskExecutions; i++) {
70 if (executions === taskExecutions) {
83 const runPoolifierPoolBenchmark = async (
88 { taskExecutions, workerData }
90 return await new Promise((resolve, reject) => {
91 const pool = buildPoolifierPool(workerType, poolType, poolSize)
93 const suite = new Benchmark.Suite(name)
94 for (const workerChoiceStrategy of Object.values(
95 WorkerChoiceStrategies
97 for (const enableTasksQueue of [false, true]) {
98 if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
99 for (const measurement of [
100 Measurements.runTime,
104 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
105 enableTasksQueue ? 'with' : 'without'
108 pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
111 pool.enableTasksQueue(enableTasksQueue)
113 pool.opts.workerChoiceStrategy,
116 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
118 pool.opts.workerChoiceStrategyOptions.measurement,
121 await runPoolifierPool(pool, {
130 `${name} with ${workerChoiceStrategy} and ${
131 enableTasksQueue ? 'with' : 'without'
134 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
135 pool.enableTasksQueue(enableTasksQueue)
137 pool.opts.workerChoiceStrategy,
140 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
141 await runPoolifierPool(pool, {
151 .on('cycle', event => {
152 console.info(event.target.toString())
154 .on('complete', function () {
157 LIST_FORMATTER.format(this.filter('fastest').map('name'))
159 const destroyTimeout = setTimeout(() => {
160 console.error('Pool destroy timeout reached (30s)')
168 clearTimeout(destroyTimeout)
172 .run({ async: true })
184 const LIST_FORMATTER = new Intl.ListFormat('en-US', {
189 const jsonIntegerSerialization = n => {
190 for (let i = 0; i < n; i++) {
200 * @param {number} n - The number of fibonacci numbers to generate.
201 * @returns {number} - The nth fibonacci number.
203 const fibonacci = n => {
216 * @param {number} n - The number to calculate the factorial of.
217 * @returns {number} - The factorial of n.
219 const factorial = n => {
220 if (n === 0 || n === 1) {
225 for (let i = 1n; i <= n; i++) {
232 const readWriteFiles = (
234 baseDirectory = `/tmp/poolifier-benchmarks/${randomInt(281474976710655)}`
236 if (existsSync(baseDirectory) === true) {
237 rmSync(baseDirectory, { recursive: true })
239 mkdirSync(baseDirectory, { recursive: true })
240 for (let i = 0; i < n; i++) {
241 const filePath = `${baseDirectory}/${i}`
242 writeFileSync(filePath, i.toString(), {
246 readFileSync(filePath, 'utf8')
248 rmSync(baseDirectory, { recursive: true })
252 const executeTaskFunction = data => {
253 switch (data.function) {
254 case TaskFunctions.jsonIntegerSerialization:
255 return jsonIntegerSerialization(data.taskSize || 1000)
256 case TaskFunctions.fibonacci:
257 return fibonacci(data.taskSize || 1000)
258 case TaskFunctions.factorial:
259 return factorial(data.taskSize || 1000)
260 case TaskFunctions.readWriteFiles:
261 return readWriteFiles(data.taskSize || 1000)
263 throw new Error('Unknown task function')
270 runPoolifierPoolBenchmark