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)
92 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 * Intentionally inefficient implementation.
201 * @param {number} n - The number of fibonacci numbers to generate.
202 * @returns {number} - The nth fibonacci number.
204 const fibonacci = n => {
206 return fibonacci(n - 1) + fibonacci(n - 2)
210 * Intentionally inefficient implementation.
211 * @param {number} n - The number to calculate the factorial of.
212 * @returns {number} - The factorial of n.
214 const factorial = n => {
218 return factorial(n - 1) * n
221 const readWriteFiles = (
223 baseDirectory = `/tmp/poolifier-benchmarks/${randomInt(281474976710655)}`
225 if (existsSync(baseDirectory) === true) {
226 rmSync(baseDirectory, { recursive: true })
228 mkdirSync(baseDirectory, { recursive: true })
229 for (let i = 0; i < n; i++) {
230 const filePath = `${baseDirectory}/${i}`
231 writeFileSync(filePath, i.toString(), {
235 readFileSync(filePath, 'utf8')
237 rmSync(baseDirectory, { recursive: true })
241 const executeTaskFunction = data => {
242 switch (data.function) {
243 case TaskFunctions.jsonIntegerSerialization:
244 return jsonIntegerSerialization(data.taskSize || 1000)
245 case TaskFunctions.fibonacci:
246 return fibonacci(data.taskSize || 1000)
247 case TaskFunctions.factorial:
248 return factorial(data.taskSize || 1000)
249 case TaskFunctions.readWriteFiles:
250 return readWriteFiles(data.taskSize || 1000)
252 throw new Error('Unknown task function')
259 runPoolifierPoolBenchmark