perf(benchmark): port to homemade mitata fork
[poolifier.git] / benchmarks / benchmarks-utils.mjs
index 03596b276c3cae5abd1b9fc074e11f7442ddf6ca..48101fdaadc434073f81906a0ad0d7095e3f675a 100644 (file)
@@ -1,7 +1,7 @@
 import { strictEqual } from 'node:assert'
 
 import Benchmark from 'benchmark'
-import { bench, group } from 'mitata'
+import { bench, clear, group, run } from 'mitata'
 
 import {
   DynamicClusterPool,
@@ -76,6 +76,77 @@ const runPoolifierPool = async (pool, { taskExecutions, workerData }) => {
 }
 
 export const runPoolifierBenchmarkBenchmarkJs = async (
+  name,
+  workerType,
+  poolType,
+  poolSize,
+  poolOptions,
+  { taskExecutions, workerData }
+) => {
+  return await new Promise((resolve, reject) => {
+    const pool = buildPoolifierPool(workerType, poolType, poolSize, poolOptions)
+    let workerChoiceStrategy
+    let enableTasksQueue
+    let workerChoiceStrategyOptions
+    if (poolOptions != null) {
+      ({
+        workerChoiceStrategy,
+        enableTasksQueue,
+        workerChoiceStrategyOptions
+      } = poolOptions)
+    }
+    const measurement = workerChoiceStrategyOptions?.measurement
+    new Benchmark(
+      `${name} with ${workerChoiceStrategy ?? pool.opts.workerChoiceStrategy}${
+        measurement != null ? `, with ${measurement}` : ''
+      } and ${enableTasksQueue ? 'with' : 'without'} tasks queue`,
+      async () => {
+        await runPoolifierPool(pool, {
+          taskExecutions,
+          workerData
+        })
+      },
+      {
+        onStart: () => {
+          if (workerChoiceStrategy != null) {
+            strictEqual(pool.opts.workerChoiceStrategy, workerChoiceStrategy)
+          }
+          if (enableTasksQueue != null) {
+            strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
+          }
+          if (measurement != null) {
+            strictEqual(
+              pool.opts.workerChoiceStrategyOptions.measurement,
+              measurement
+            )
+          }
+        },
+        onComplete: event => {
+          console.info(event.target.toString())
+          if (pool.started && !pool.destroying) {
+            pool.destroy().then(resolve).catch(reject)
+          } else {
+            resolve()
+          }
+        },
+        onError: event => {
+          if (pool.started && !pool.destroying) {
+            pool
+              .destroy()
+              .then(() => {
+                return reject(event.target.error)
+              })
+              .catch(() => {})
+          } else {
+            reject(event.target.error)
+          }
+        }
+      }
+    ).run({ async: true })
+  })
+}
+
+export const runPoolifierBenchmarkBenchmarkJsSuite = async (
   name,
   workerType,
   poolType,
@@ -84,22 +155,46 @@ export const runPoolifierBenchmarkBenchmarkJs = async (
 ) => {
   return await new Promise((resolve, reject) => {
     const pool = buildPoolifierPool(workerType, poolType, poolSize)
-    try {
-      const suite = new Benchmark.Suite(name)
-      for (const workerChoiceStrategy of Object.values(
-        WorkerChoiceStrategies
-      )) {
-        for (const enableTasksQueue of [false, true]) {
-          if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
-            for (const measurement of [
-              Measurements.runTime,
-              Measurements.elu
-            ]) {
-              suite.add(
-                `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
-                  enableTasksQueue ? 'with' : 'without'
-                } tasks queue`,
-                async () => {
+    const suite = new Benchmark.Suite(name, {
+      onComplete: () => {
+        if (pool.started && !pool.destroying) {
+          pool.destroy().then(resolve).catch(reject)
+        } else {
+          resolve()
+        }
+      },
+      onCycle: event => {
+        console.info(event.target.toString())
+      },
+      onError: event => {
+        if (pool.started && !pool.destroying) {
+          pool
+            .destroy()
+            .then(() => {
+              return reject(event.target.error)
+            })
+            .catch(() => {})
+        } else {
+          reject(event.target.error)
+        }
+      }
+    })
+    for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
+      for (const enableTasksQueue of [false, true]) {
+        if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
+          for (const measurement of [Measurements.runTime, Measurements.elu]) {
+            suite.add(
+              `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
+                enableTasksQueue ? 'with' : 'without'
+              } tasks queue`,
+              async () => {
+                await runPoolifierPool(pool, {
+                  taskExecutions,
+                  workerData
+                })
+              },
+              {
+                onStart: () => {
                   pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
                     measurement
                   })
@@ -113,19 +208,23 @@ export const runPoolifierBenchmarkBenchmarkJs = async (
                     pool.opts.workerChoiceStrategyOptions.measurement,
                     measurement
                   )
-                  await runPoolifierPool(pool, {
-                    taskExecutions,
-                    workerData
-                  })
                 }
-              )
-            }
-          } else {
-            suite.add(
-              `${name} with ${workerChoiceStrategy} and ${
-                enableTasksQueue ? 'with' : 'without'
-              } tasks queue`,
-              async () => {
+              }
+            )
+          }
+        } else {
+          suite.add(
+            `${name} with ${workerChoiceStrategy} and ${
+              enableTasksQueue ? 'with' : 'without'
+            } tasks queue`,
+            async () => {
+              await runPoolifierPool(pool, {
+                taskExecutions,
+                workerData
+              })
+            },
+            {
+              onStart: () => {
                 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
                 pool.enableTasksQueue(enableTasksQueue)
                 strictEqual(
@@ -133,50 +232,24 @@ export const runPoolifierBenchmarkBenchmarkJs = async (
                   workerChoiceStrategy
                 )
                 strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
-                await runPoolifierPool(pool, {
-                  taskExecutions,
-                  workerData
-                })
               }
-            )
-          }
+            }
+          )
         }
       }
-      suite
-        .on('cycle', event => {
-          console.info(event.target.toString())
-        })
-        .on('complete', function () {
-          console.info(
-            'Fastest is ' +
-              LIST_FORMATTER.format(this.filter('fastest').map('name'))
-          )
-          const destroyTimeout = setTimeout(() => {
-            console.error('Pool destroy timeout reached (30s)')
-            resolve()
-          }, 30000)
-          pool
-            .destroy()
-            .then(resolve)
-            .catch(reject)
-            .finally(() => {
-              clearTimeout(destroyTimeout)
-            })
-            .catch(() => {})
-        })
-        .run({ async: true })
-    } catch (error) {
-      pool
-        .destroy()
-        .then(() => {
-          return reject(error)
-        })
-        .catch(() => {})
     }
+    suite
+      .on('complete', function () {
+        console.info(
+          'Fastest is ' +
+            LIST_FORMATTER.format(this.filter('fastest').map('name'))
+        )
+      })
+      .run({ async: true })
   })
 }
 
-export const buildPoolifierBenchmarkMitata = (
+export const runPoolifierBenchmarkMitata = async (
   name,
   workerType,
   poolType,
@@ -240,7 +313,9 @@ export const buildPoolifierBenchmarkMitata = (
         }
       }
     }
-    return pool
+    await run()
+    await pool.destroy()
+    clear()
   } catch (error) {
     console.error(error)
   }