perf: fix continuous benchmarking
[poolifier.git] / benchmarks / benchmarks-utils.mjs
CommitLineData
0804b9b4
JB
1import { strictEqual } from 'node:assert'
2
98f60ddd 3import { bench, clear, group, run } from 'tatami-ng'
0804b9b4
JB
4
5import {
6 DynamicClusterPool,
7 DynamicThreadPool,
8 FixedClusterPool,
9 FixedThreadPool,
10 Measurements,
11 PoolTypes,
12 WorkerChoiceStrategies,
13 WorkerTypes
14} from '../lib/index.mjs'
a6bef8d2 15import { executeTaskFunction } from './benchmarks-utils.cjs'
0804b9b4
JB
16
17const buildPoolifierPool = (workerType, poolType, poolSize, poolOptions) => {
18 switch (poolType) {
19 case PoolTypes.fixed:
20 switch (workerType) {
21 case WorkerTypes.thread:
22 return new FixedThreadPool(
23 poolSize,
24 './benchmarks/internal/thread-worker.mjs',
25 poolOptions
26 )
27 case WorkerTypes.cluster:
28 return new FixedClusterPool(
29 poolSize,
30 './benchmarks/internal/cluster-worker.cjs',
31 poolOptions
32 )
33 }
34 break
35 case PoolTypes.dynamic:
36 switch (workerType) {
37 case WorkerTypes.thread:
38 return new DynamicThreadPool(
39 Math.floor(poolSize / 2),
40 poolSize,
41 './benchmarks/internal/thread-worker.mjs',
42 poolOptions
43 )
44 case WorkerTypes.cluster:
45 return new DynamicClusterPool(
46 Math.floor(poolSize / 2),
47 poolSize,
48 './benchmarks/internal/cluster-worker.cjs',
49 poolOptions
50 )
51 }
52 break
53 }
54}
55
56const runPoolifierPool = async (pool, { taskExecutions, workerData }) => {
57 return await new Promise((resolve, reject) => {
58 let executions = 0
59 for (let i = 1; i <= taskExecutions; i++) {
60 pool
61 .execute(workerData)
62 .then(() => {
63 ++executions
64 if (executions === taskExecutions) {
65 resolve({ ok: 1 })
66 }
67 return undefined
68 })
69 .catch(err => {
70 console.error(err)
71 reject(err)
72 })
73 }
74 })
75}
76
b5ca7c94 77export const runPoolifierBenchmarkTatamiNg = async (
0804b9b4
JB
78 name,
79 workerType,
80 poolType,
81 poolSize,
82 { taskExecutions, workerData }
83) => {
84 try {
85 const pool = buildPoolifierPool(workerType, poolType, poolSize)
86 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
87 for (const enableTasksQueue of [false, true]) {
88 if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
89 for (const measurement of [Measurements.runTime, Measurements.elu]) {
90 group(name, () => {
91 bench(
92 `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
93 enableTasksQueue ? 'with' : 'without'
94 } tasks queue`,
95 async () => {
0804b9b4
JB
96 await runPoolifierPool(pool, {
97 taskExecutions,
98 workerData
99 })
2baf75cf
JB
100 },
101 {
102 before: () => {
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 }
0804b9b4
JB
117 }
118 )
119 })
120 }
121 } else {
122 group(name, () => {
123 bench(
124 `${name} with ${workerChoiceStrategy} and ${
125 enableTasksQueue ? 'with' : 'without'
126 } tasks queue`,
127 async () => {
0804b9b4
JB
128 await runPoolifierPool(pool, {
129 taskExecutions,
130 workerData
131 })
2baf75cf
JB
132 },
133 {
134 before: () => {
135 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
136 pool.enableTasksQueue(enableTasksQueue)
137 strictEqual(
138 pool.opts.workerChoiceStrategy,
139 workerChoiceStrategy
140 )
141 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
142 }
0804b9b4
JB
143 }
144 )
145 })
146 }
147 }
148 }
8f01ffbe 149 const report = await run()
16534b42 150 clear()
2baf75cf 151 await pool.destroy()
8f01ffbe 152 return report
0804b9b4
JB
153 } catch (error) {
154 console.error(error)
155 }
156}
157
8f01ffbe
JB
158export const convertTatamiNgToBmf = report => {
159 return report.benchmarks
160 .map(({ name, stats }) => {
161 return {
162 [name]: {
163 latency: {
164 value: stats?.avg,
165 lower_value: stats?.min,
166 upper_value: stats?.max
167 },
168 throughput: {
169 value: stats?.iter
170 }
171 }
172 }
173 })
174 .reduce((obj, item) => Object.assign(obj, item), {})
175}
a6bef8d2
JB
176
177export { executeTaskFunction }