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 (
82 { taskExecutions
, workerData
}
84 const pool
= buildPoolifierPool(workerType
, poolType
, poolSize
)
85 const suite
= new Benchmark
.Suite(name
)
86 return await
new Promise((resolve
, reject
) => {
88 for (const workerChoiceStrategy
of Object
.values(
89 WorkerChoiceStrategies
91 for (const enableTasksQueue
of [false, true]) {
92 if (workerChoiceStrategy
=== WorkerChoiceStrategies
.FAIR_SHARE
) {
93 for (const measurement
of [
98 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
99 enableTasksQueue ? 'with' : 'without'
102 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
, {
105 pool
.enableTasksQueue(enableTasksQueue
)
107 pool
.opts
.workerChoiceStrategy
,
111 pool
.opts
.enableTasksQueue
,
115 pool
.opts
.workerChoiceStrategyOptions
.measurement
,
118 await
runPoolifierPool(pool
, {
127 `${name} with ${workerChoiceStrategy} and ${
128 enableTasksQueue ? 'with' : 'without'
131 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
132 pool
.enableTasksQueue(enableTasksQueue
)
134 pool
.opts
.workerChoiceStrategy
,
137 assert
.strictEqual(pool
.opts
.enableTasksQueue
, enableTasksQueue
)
138 await
runPoolifierPool(pool
, {
148 .on('cycle', event
=> {
149 console
.info(event
.target
.toString())
151 .on('complete', async
function () {
154 LIST_FORMATTER
.format(this.filter('fastest').map('name'))
159 .run({ async
: true })
171 const LIST_FORMATTER
= new Intl
.ListFormat('en-US', {
176 const generateRandomInteger
= (max
= Number
.MAX_SAFE_INTEGER
, min
= 0) => {
177 if (max
< min
|| max
< 0 || min
< 0) {
178 throw new RangeError('Invalid interval')
180 max
= Math
.floor(max
)
181 if (min
!= null && min
!== 0) {
183 return Math
.floor(Math
.random() * (max
- min
+ 1)) + min
185 return Math
.floor(Math
.random() * (max
+ 1))
188 const jsonIntegerSerialization
= n
=> {
189 for (let i
= 0; i
< n
; i
++) {
199 * Intentionally inefficient implementation.
200 * @param {number} n - The number of fibonacci numbers to generate.
201 * @returns {number} - The nth fibonacci number.
203 const fibonacci
= n
=> {
205 return fibonacci(n
- 1) + fibonacci(n
- 2)
209 * Intentionally inefficient implementation.
210 * @param {number} n - The number to calculate the factorial of.
211 * @returns {number} - The factorial of n.
213 const factorial
= n
=> {
217 return factorial(n
- 1) * n
220 const readWriteFiles
= (
222 baseDirectory
= `/tmp/poolifier-benchmarks/${crypto.randomInt(
226 if (fs
.existsSync(baseDirectory
) === true) {
227 fs
.rmSync(baseDirectory
, { recursive
: true })
229 fs
.mkdirSync(baseDirectory
, { recursive
: true })
230 for (let i
= 0; i
< n
; i
++) {
231 const filePath
= `${baseDirectory}/${i}`
232 fs
.writeFileSync(filePath
, i
.toString(), {
236 fs
.readFileSync(filePath
, 'utf8')
238 fs
.rmSync(baseDirectory
, { recursive
: true })
242 const executeTaskFunction
= data
=> {
243 switch (data
.function) {
244 case TaskFunctions
.jsonIntegerSerialization
:
245 return jsonIntegerSerialization(data
.taskSize
|| 1000)
246 case TaskFunctions
.fibonacci
:
247 return fibonacci(data
.taskSize
|| 1000)
248 case TaskFunctions
.factorial
:
249 return factorial(data
.taskSize
|| 1000)
250 case TaskFunctions
.readWriteFiles
:
251 return readWriteFiles(data
.taskSize
|| 1000)
253 throw new Error('Unknown task function')
260 generateRandomInteger
,
261 runPoolifierPoolBenchmark