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