fix(benchmark): add missing export
[poolifier.git] / benchmarks / benchmarks-utils.mjs
CommitLineData
0804b9b4
JB
1import { strictEqual } from 'node:assert'
2
3import Benchmark from 'benchmark'
4import { bench, group } from 'mitata'
5
6import {
7 DynamicClusterPool,
8 DynamicThreadPool,
9 FixedClusterPool,
10 FixedThreadPool,
11 Measurements,
12 PoolTypes,
13 WorkerChoiceStrategies,
14 WorkerTypes
15} from '../lib/index.mjs'
a6bef8d2 16import { executeTaskFunction } from './benchmarks-utils.cjs'
0804b9b4
JB
17
18const buildPoolifierPool = (workerType, poolType, poolSize, poolOptions) => {
19 switch (poolType) {
20 case PoolTypes.fixed:
21 switch (workerType) {
22 case WorkerTypes.thread:
23 return new FixedThreadPool(
24 poolSize,
25 './benchmarks/internal/thread-worker.mjs',
26 poolOptions
27 )
28 case WorkerTypes.cluster:
29 return new FixedClusterPool(
30 poolSize,
31 './benchmarks/internal/cluster-worker.cjs',
32 poolOptions
33 )
34 }
35 break
36 case PoolTypes.dynamic:
37 switch (workerType) {
38 case WorkerTypes.thread:
39 return new DynamicThreadPool(
40 Math.floor(poolSize / 2),
41 poolSize,
42 './benchmarks/internal/thread-worker.mjs',
43 poolOptions
44 )
45 case WorkerTypes.cluster:
46 return new DynamicClusterPool(
47 Math.floor(poolSize / 2),
48 poolSize,
49 './benchmarks/internal/cluster-worker.cjs',
50 poolOptions
51 )
52 }
53 break
54 }
55}
56
57const runPoolifierPool = async (pool, { taskExecutions, workerData }) => {
58 return await new Promise((resolve, reject) => {
59 let executions = 0
60 for (let i = 1; i <= taskExecutions; i++) {
61 pool
62 .execute(workerData)
63 .then(() => {
64 ++executions
65 if (executions === taskExecutions) {
66 resolve({ ok: 1 })
67 }
68 return undefined
69 })
70 .catch(err => {
71 console.error(err)
72 reject(err)
73 })
74 }
75 })
76}
77
78export const runPoolifierBenchmarkBenchmarkJs = async (
79 name,
80 workerType,
81 poolType,
82 poolSize,
83 { taskExecutions, workerData }
84) => {
85 return await new Promise((resolve, reject) => {
86 const pool = buildPoolifierPool(workerType, poolType, poolSize)
87 try {
88 const suite = new Benchmark.Suite(name)
89 for (const workerChoiceStrategy of Object.values(
90 WorkerChoiceStrategies
91 )) {
92 for (const enableTasksQueue of [false, true]) {
93 if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
94 for (const measurement of [
95 Measurements.runTime,
96 Measurements.elu
97 ]) {
98 suite.add(
99 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
100 enableTasksQueue ? 'with' : 'without'
101 } tasks queue`,
102 async () => {
103 pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
104 measurement
105 })
106 pool.enableTasksQueue(enableTasksQueue)
107 strictEqual(
108 pool.opts.workerChoiceStrategy,
109 workerChoiceStrategy
110 )
111 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
112 strictEqual(
113 pool.opts.workerChoiceStrategyOptions.measurement,
114 measurement
115 )
116 await runPoolifierPool(pool, {
117 taskExecutions,
118 workerData
119 })
120 }
121 )
122 }
123 } else {
124 suite.add(
125 `${name} with ${workerChoiceStrategy} and ${
126 enableTasksQueue ? 'with' : 'without'
127 } tasks queue`,
128 async () => {
129 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
130 pool.enableTasksQueue(enableTasksQueue)
131 strictEqual(
132 pool.opts.workerChoiceStrategy,
133 workerChoiceStrategy
134 )
135 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
136 await runPoolifierPool(pool, {
137 taskExecutions,
138 workerData
139 })
140 }
141 )
142 }
143 }
144 }
145 suite
146 .on('cycle', event => {
147 console.info(event.target.toString())
148 })
149 .on('complete', function () {
150 console.info(
151 'Fastest is ' +
152 LIST_FORMATTER.format(this.filter('fastest').map('name'))
153 )
154 const destroyTimeout = setTimeout(() => {
155 console.error('Pool destroy timeout reached (30s)')
156 resolve()
157 }, 30000)
158 pool
159 .destroy()
160 .then(resolve)
161 .catch(reject)
162 .finally(() => {
163 clearTimeout(destroyTimeout)
164 })
165 .catch(() => {})
166 })
167 .run({ async: true })
168 } catch (error) {
169 pool
170 .destroy()
171 .then(() => {
172 return reject(error)
173 })
174 .catch(() => {})
175 }
176 })
177}
178
179export const buildPoolifierBenchmarkMitata = (
180 name,
181 workerType,
182 poolType,
183 poolSize,
184 { taskExecutions, workerData }
185) => {
186 try {
187 const pool = buildPoolifierPool(workerType, poolType, poolSize)
188 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
189 for (const enableTasksQueue of [false, true]) {
190 if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
191 for (const measurement of [Measurements.runTime, Measurements.elu]) {
192 group(name, () => {
193 bench(
194 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
195 enableTasksQueue ? 'with' : 'without'
196 } tasks queue`,
197 async () => {
198 pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
199 measurement
200 })
201 pool.enableTasksQueue(enableTasksQueue)
202 strictEqual(
203 pool.opts.workerChoiceStrategy,
204 workerChoiceStrategy
205 )
206 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
207 strictEqual(
208 pool.opts.workerChoiceStrategyOptions.measurement,
209 measurement
210 )
211 await runPoolifierPool(pool, {
212 taskExecutions,
213 workerData
214 })
215 }
216 )
217 })
218 }
219 } else {
220 group(name, () => {
221 bench(
222 `${name} with ${workerChoiceStrategy} and ${
223 enableTasksQueue ? 'with' : 'without'
224 } tasks queue`,
225 async () => {
226 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
227 pool.enableTasksQueue(enableTasksQueue)
228 strictEqual(
229 pool.opts.workerChoiceStrategy,
230 workerChoiceStrategy
231 )
232 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
233 await runPoolifierPool(pool, {
234 taskExecutions,
235 workerData
236 })
237 }
238 )
239 })
240 }
241 }
242 }
243 return pool
244 } catch (error) {
245 console.error(error)
246 }
247}
248
249const LIST_FORMATTER = new Intl.ListFormat('en-US', {
250 style: 'long',
251 type: 'conjunction'
252})
a6bef8d2
JB
253
254export { executeTaskFunction }