1 const crypto
= require('node:crypto')
2 const assert
= require('node:assert')
3 const fs
= require('node:fs')
4 const Benchmark
= require('benchmark')
12 WorkerChoiceStrategies
,
14 } = require('../lib/index.js')
15 const { TaskFunctions
} = require('./benchmarks-types.js')
17 const buildPoolifierPool
= (workerType
, poolType
, poolSize
, poolOptions
) => {
21 case WorkerTypes
.thread
:
22 return new FixedThreadPool(
24 './benchmarks/internal/thread-worker.mjs',
27 case WorkerTypes
.cluster
:
28 return new FixedClusterPool(
30 './benchmarks/internal/cluster-worker.js',
35 case PoolTypes
.dynamic
:
37 case WorkerTypes
.thread
:
38 return new DynamicThreadPool(
39 Math
.floor(poolSize
/ 2),
41 './benchmarks/internal/thread-worker.mjs',
44 case WorkerTypes
.cluster
:
45 return new DynamicClusterPool(
46 Math
.floor(poolSize
/ 2),
48 './benchmarks/internal/cluster-worker.js',
56 const runPoolifierPool
= async (pool
, { taskExecutions
, workerData
}) => {
57 return await
new Promise((resolve
, reject
) => {
59 for (let i
= 1; i
<= taskExecutions
; i
++) {
64 if (executions
=== taskExecutions
) {
77 const runPoolifierPoolBenchmark
= async (
80 { taskExecutions
, workerData
}
82 return await
new Promise((resolve
, reject
) => {
84 const suite
= new Benchmark
.Suite(name
)
85 for (const workerChoiceStrategy
of Object
.values(
86 WorkerChoiceStrategies
88 for (const enableTasksQueue
of [false, true]) {
89 if (workerChoiceStrategy
=== WorkerChoiceStrategies
.FAIR_SHARE
) {
90 for (const measurement
of [
95 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
96 enableTasksQueue ? 'with' : 'without'
99 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
, {
102 pool
.enableTasksQueue(enableTasksQueue
)
104 pool
.opts
.workerChoiceStrategy
,
108 pool
.opts
.enableTasksQueue
,
112 pool
.opts
.workerChoiceStrategyOptions
.measurement
,
115 await
runPoolifierPool(pool
, {
124 `${name} with ${workerChoiceStrategy} and ${
125 enableTasksQueue ? 'with' : 'without'
128 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
129 pool
.enableTasksQueue(enableTasksQueue
)
131 pool
.opts
.workerChoiceStrategy
,
134 assert
.strictEqual(pool
.opts
.enableTasksQueue
, enableTasksQueue
)
135 await
runPoolifierPool(pool
, {
145 .on('cycle', event
=> {
146 console
.info(event
.target
.toString())
148 .on('complete', async
function () {
151 LIST_FORMATTER
.format(this.filter('fastest').map('name'))
157 .run({ async
: true })
164 const LIST_FORMATTER
= new Intl
.ListFormat('en-US', {
169 const generateRandomInteger
= (max
= Number
.MAX_SAFE_INTEGER
, min
= 0) => {
170 if (max
< min
|| max
< 0 || min
< 0) {
171 throw new RangeError('Invalid interval')
173 max
= Math
.floor(max
)
174 if (min
!= null && min
!== 0) {
176 return Math
.floor(Math
.random() * (max
- min
+ 1)) + min
178 return Math
.floor(Math
.random() * (max
+ 1))
181 const jsonIntegerSerialization
= n
=> {
182 for (let i
= 0; i
< n
; i
++) {
192 * Intentionally inefficient implementation.
193 * @param {number} n - The number of fibonacci numbers to generate.
194 * @returns {number} - The nth fibonacci number.
196 const fibonacci
= n
=> {
198 return fibonacci(n
- 1) + fibonacci(n
- 2)
202 * Intentionally inefficient implementation.
203 * @param {number} n - The number to calculate the factorial of.
204 * @returns {number} - The factorial of n.
206 const factorial
= n
=> {
210 return factorial(n
- 1) * n
213 const readWriteFiles
= (
215 baseDirectory
= `/tmp/poolifier-benchmarks/${crypto.randomInt(
219 if (fs
.existsSync(baseDirectory
) === true) {
220 fs
.rmSync(baseDirectory
, { recursive
: true })
222 fs
.mkdirSync(baseDirectory
, { recursive
: true })
223 for (let i
= 0; i
< n
; i
++) {
224 const filePath
= `${baseDirectory}/${i}`
225 fs
.writeFileSync(filePath
, i
.toString(), {
229 fs
.readFileSync(filePath
, 'utf8')
231 fs
.rmSync(baseDirectory
, { recursive
: true })
235 const executeTaskFunction
= data
=> {
236 switch (data
.function) {
237 case TaskFunctions
.jsonIntegerSerialization
:
238 return jsonIntegerSerialization(data
.taskSize
|| 1000)
239 case TaskFunctions
.fibonacci
:
240 return fibonacci(data
.taskSize
|| 1000)
241 case TaskFunctions
.factorial
:
242 return factorial(data
.taskSize
|| 1000)
243 case TaskFunctions
.readWriteFiles
:
244 return readWriteFiles(data
.taskSize
|| 1000)
246 throw new Error('Unknown task function')
254 generateRandomInteger
,
255 runPoolifierPoolBenchmark