chore: v2.6.0
[poolifier.git] / benchmarks / benchmarks-utils.js
index 30af25c927c38edc190ae2c5538a9c22e4569788..eb3a4f945f40a64a95e010fe375b81c4bb874090 100644 (file)
@@ -1,15 +1,27 @@
-const { WorkerFunctions } = require('./benchmarks-types')
+const crypto = require('crypto')
+const fs = require('fs')
+const {
+  DynamicClusterPool,
+  DynamicThreadPool,
+  FixedClusterPool,
+  FixedThreadPool
+} = require('../lib')
+const {
+  PoolTypes,
+  WorkerFunctions,
+  WorkerTypes
+} = require('./benchmarks-types')
 
-async function runPoolifierTest (pool, { tasks, workerData }) {
+async function runTest (pool, { taskExecutions, workerData }) {
   return new Promise((resolve, reject) => {
     let executions = 0
-    for (let i = 1; i <= tasks; i++) {
+    for (let i = 1; i <= taskExecutions; i++) {
       pool
         .execute(workerData)
         .then(() => {
-          executions++
-          if (executions === tasks) {
-            return resolve('FINISH')
+          ++executions
+          if (executions === taskExecutions) {
+            return resolve({ ok: 1 })
           }
           return null
         })
@@ -21,6 +33,18 @@ async function runPoolifierTest (pool, { tasks, workerData }) {
   })
 }
 
+function generateRandomInteger (max = Number.MAX_SAFE_INTEGER, min = 0) {
+  if (max < min || max < 0 || min < 0) {
+    throw new RangeError('Invalid interval')
+  }
+  max = Math.floor(max)
+  if (min != null && min !== 0) {
+    min = Math.ceil(min)
+    return Math.floor(Math.random() * (max - min + 1)) + min
+  }
+  return Math.floor(Math.random() * (max + 1))
+}
+
 function jsonIntegerSerialization (n) {
   for (let i = 0; i < n; i++) {
     const o = {
@@ -30,18 +54,8 @@ function jsonIntegerSerialization (n) {
   }
 }
 
-function generateRandomInteger (max = Number.MAX_SAFE_INTEGER, min = 0) {
-  max = Math.floor(max)
-  if (min) {
-    min = Math.ceil(min)
-    return Math.floor(Math.random() * (max - min + 1)) + min
-  }
-  return Math.floor(Math.random() * (max + 1))
-}
-
 /**
  * Intentionally inefficient implementation.
- *
  * @param {number} n - The number of fibonacci numbers to generate.
  * @returns {number} - The nth fibonacci number.
  */
@@ -52,16 +66,35 @@ function fibonacci (n) {
 
 /**
  * Intentionally inefficient implementation.
- *
  * @param {number} n - The number to calculate the factorial of.
  * @returns {number} - The factorial of n.
  */
 function factorial (n) {
   if (n === 0) {
     return 1
-  } else {
-    return factorial(n - 1) * n
   }
+  return factorial(n - 1) * n
+}
+
+function readWriteFiles (
+  n,
+  baseDirectory = `/tmp/poolifier-benchmarks/${crypto.randomInt(
+    281474976710655
+  )}`
+) {
+  if (fs.existsSync(baseDirectory) === true) {
+    fs.rmSync(baseDirectory, { recursive: true })
+  }
+  fs.mkdirSync(baseDirectory, { recursive: true })
+  for (let i = 0; i < n; i++) {
+    const filePath = `${baseDirectory}/${i}`
+    fs.writeFileSync(filePath, i.toString(), {
+      encoding: 'utf8',
+      flag: 'a'
+    })
+    fs.readFileSync(filePath, 'utf8')
+  }
+  fs.rmSync(baseDirectory, { recursive: true })
 }
 
 function executeWorkerFunction (data) {
@@ -72,20 +105,57 @@ function executeWorkerFunction (data) {
       return fibonacci(data.taskSize || 1000)
     case WorkerFunctions.factorial:
       return factorial(data.taskSize || 1000)
+    case WorkerFunctions.readWriteFiles:
+      return readWriteFiles(data.taskSize || 1000)
     default:
       throw new Error('Unknown worker function')
   }
 }
 
-const LIST_FORMATTER = new Intl.ListFormat('en-US', {
-  style: 'long',
-  type: 'conjunction'
-})
+function buildPool (workerType, poolType, poolSize, poolOptions) {
+  switch (poolType) {
+    case PoolTypes.fixed:
+      switch (workerType) {
+        case WorkerTypes.thread:
+          return new FixedThreadPool(
+            poolSize,
+            './benchmarks/internal/thread-worker.js',
+            poolOptions
+          )
+        case WorkerTypes.cluster:
+          return new FixedClusterPool(
+            poolSize,
+            './benchmarks/internal/cluster-worker.js',
+            poolOptions
+          )
+      }
+      break
+    case PoolTypes.dynamic:
+      switch (workerType) {
+        case WorkerTypes.thread:
+          return new DynamicThreadPool(
+            poolSize / 2,
+            poolSize * 3,
+            './benchmarks/internal/thread-worker.js',
+            poolOptions
+          )
+        case WorkerTypes.cluster:
+          return new DynamicClusterPool(
+            poolSize / 2,
+            poolSize * 3,
+            './benchmarks/internal/cluster-worker.js',
+            poolOptions
+          )
+      }
+      break
+  }
+}
 
 module.exports = {
-  LIST_FORMATTER,
   WorkerFunctions,
+  buildPool,
   executeWorkerFunction,
   generateRandomInteger,
-  runPoolifierTest
+  readWriteFiles,
+  runTest
 }