fix(benchmark): remove timeouting in benchmark.js
[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) => {
6aec0be3 86 const pool = buildPoolifierPool(workerType, poolType, poolSize)
0804b9b4 87 try {
fe7488e9
JB
88 const suite = new Benchmark.Suite(name, {
89 onComplete: () => {
6aec0be3
JB
90 if (pool.started && !pool.destroying) {
91 pool.destroy().then(resolve).catch(reject)
92 } else {
fe7488e9 93 resolve()
6aec0be3 94 }
fe7488e9
JB
95 },
96 onCycle: event => {
97 console.info(event.target.toString())
98 },
99 onError: event => {
6aec0be3
JB
100 if (pool.started && !pool.destroying) {
101 pool
102 .destroy()
103 .then(() => {
104 return reject(event.target.error)
105 })
106 .catch(() => {})
107 } else {
108 reject(event.target.error)
109 }
fe7488e9
JB
110 }
111 })
0804b9b4
JB
112 for (const workerChoiceStrategy of Object.values(
113 WorkerChoiceStrategies
114 )) {
115 for (const enableTasksQueue of [false, true]) {
116 if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
117 for (const measurement of [
118 Measurements.runTime,
119 Measurements.elu
120 ]) {
121 suite.add(
fe7488e9 122 `${name} with ${workerChoiceStrategy}, with measurement ${measurement} and ${
0804b9b4
JB
123 enableTasksQueue ? 'with' : 'without'
124 } tasks queue`,
125 async () => {
0804b9b4
JB
126 await runPoolifierPool(pool, {
127 taskExecutions,
128 workerData
129 })
083213c6
JB
130 },
131 {
132 onStart: () => {
133 pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
134 measurement
135 })
136 pool.enableTasksQueue(enableTasksQueue)
137 strictEqual(
138 pool.opts.workerChoiceStrategy,
139 workerChoiceStrategy
140 )
141 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
142 strictEqual(
143 pool.opts.workerChoiceStrategyOptions.measurement,
144 measurement
145 )
146 }
0804b9b4
JB
147 }
148 )
149 }
150 } else {
151 suite.add(
152 `${name} with ${workerChoiceStrategy} and ${
153 enableTasksQueue ? 'with' : 'without'
154 } tasks queue`,
155 async () => {
0804b9b4
JB
156 await runPoolifierPool(pool, {
157 taskExecutions,
158 workerData
159 })
083213c6
JB
160 },
161 {
162 onStart: () => {
163 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
164 pool.enableTasksQueue(enableTasksQueue)
165 strictEqual(
166 pool.opts.workerChoiceStrategy,
167 workerChoiceStrategy
168 )
169 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
170 }
0804b9b4
JB
171 }
172 )
173 }
174 }
175 }
176 suite
0804b9b4
JB
177 .on('complete', function () {
178 console.info(
179 'Fastest is ' +
180 LIST_FORMATTER.format(this.filter('fastest').map('name'))
181 )
0804b9b4 182 })
df6c496b 183 .run({ async: true })
0804b9b4
JB
184 } catch (error) {
185 pool
186 .destroy()
187 .then(() => {
188 return reject(error)
189 })
190 .catch(() => {})
191 }
192 })
193}
194
195export const buildPoolifierBenchmarkMitata = (
196 name,
197 workerType,
198 poolType,
199 poolSize,
200 { taskExecutions, workerData }
201) => {
202 try {
203 const pool = buildPoolifierPool(workerType, poolType, poolSize)
204 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
205 for (const enableTasksQueue of [false, true]) {
206 if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
207 for (const measurement of [Measurements.runTime, Measurements.elu]) {
208 group(name, () => {
209 bench(
210 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
211 enableTasksQueue ? 'with' : 'without'
212 } tasks queue`,
213 async () => {
214 pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
215 measurement
216 })
217 pool.enableTasksQueue(enableTasksQueue)
218 strictEqual(
219 pool.opts.workerChoiceStrategy,
220 workerChoiceStrategy
221 )
222 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
223 strictEqual(
224 pool.opts.workerChoiceStrategyOptions.measurement,
225 measurement
226 )
227 await runPoolifierPool(pool, {
228 taskExecutions,
229 workerData
230 })
231 }
232 )
233 })
234 }
235 } else {
236 group(name, () => {
237 bench(
238 `${name} with ${workerChoiceStrategy} and ${
239 enableTasksQueue ? 'with' : 'without'
240 } tasks queue`,
241 async () => {
242 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
243 pool.enableTasksQueue(enableTasksQueue)
244 strictEqual(
245 pool.opts.workerChoiceStrategy,
246 workerChoiceStrategy
247 )
248 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
249 await runPoolifierPool(pool, {
250 taskExecutions,
251 workerData
252 })
253 }
254 )
255 })
256 }
257 }
258 }
259 return pool
260 } catch (error) {
261 console.error(error)
262 }
263}
264
265const LIST_FORMATTER = new Intl.ListFormat('en-US', {
266 style: 'long',
267 type: 'conjunction'
268})
a6bef8d2
JB
269
270export { executeTaskFunction }