Improve benchmarks: add IO intensive task workload, add task size option, integrate...
authorJérôme Benoit <jerome.benoit@sap.com>
Mon, 17 Oct 2022 22:15:45 +0000 (00:15 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Mon, 17 Oct 2022 22:15:45 +0000 (00:15 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
25 files changed:
.eslintignore
.eslintrc.js
CHANGELOG.md
benchmarks/versus-external-pools/bench.sh
benchmarks/versus-external-pools/dynamic-piscina.js
benchmarks/versus-external-pools/dynamic-poolifier.js
benchmarks/versus-external-pools/dynamic-suchmokuo-node-worker-threads-pool.js
benchmarks/versus-external-pools/dynamic-worker-nodes.js
benchmarks/versus-external-pools/dynamic-workerpool.js
benchmarks/versus-external-pools/fixed-microjob.js
benchmarks/versus-external-pools/fixed-piscina.js
benchmarks/versus-external-pools/fixed-poolifier.js
benchmarks/versus-external-pools/fixed-threadwork.js
benchmarks/versus-external-pools/fixed-worker-nodes.js
benchmarks/versus-external-pools/fixed-workerpool.js
benchmarks/versus-external-pools/functions/function-to-bench.js
benchmarks/versus-external-pools/pool-threadwork.js
benchmarks/versus-external-pools/static-suchmokuo-node-worker-threads-pool.js
benchmarks/versus-external-pools/threadjs.js
benchmarks/versus-external-pools/workers/workerpool/function-to-bench-worker.js
examples/dynamicExample.js
examples/fixedExample.js
examples/typescript/pool.ts
examples/yourWorker.js
tsconfig.json

index 0786c8236503d2eabd9de78d3efd8bf376705819..f94ab6fc37e46c0075a5206d6cb80604cc056fb8 100644 (file)
@@ -1,5 +1,3 @@
-examples/typescript/**/*.ts
-benchmarks/versus-external-pools/
 docs/
 outputs/
 lib/
index f9453f90f5dd8825e45180a5f8b61004689ff444..bd39bc7e71117b77a99f34f7304123678bd73c27 100644 (file)
@@ -37,23 +37,33 @@ module.exports = defineConfig({
         skipWords: [
           'browserslist',
           'christopher',
+          'cjs',
           'comparator',
           'cpu',
           'cpus',
+          'ctx',
           'ecma',
           'enum',
           'fibonacci',
+          'fs',
           'inheritDoc',
           'jsdoc',
+          'microjob',
           'num',
           'os',
+          'piscina',
           'poolifier',
+          'poolify',
           'readonly',
           'serializable',
           'sinon',
+          'threadjs',
+          'threadwork',
           'tsconfig',
           'typedoc',
+          'unlink',
           'unregister',
+          'utf8',
           'workerpool'
         ],
         skipIfMatch: ['^@.*', '^plugin:.*']
@@ -117,6 +127,16 @@ module.exports = defineConfig({
         'jsdoc/require-returns-type': 'off'
       }
     },
+    {
+      files: ['examples/typescript/**/*.ts'],
+      rules: {
+        'import/no-unresolved': 'off',
+        'jsdoc/require-jsdoc': 'off',
+        '@typescript-eslint/no-unsafe-argument': 'off',
+        '@typescript-eslint/no-unsafe-call': 'off',
+        '@typescript-eslint/no-unsafe-assignment': 'off'
+      }
+    },
     {
       files: ['**/*.js'],
       extends: 'plugin:node/recommended'
index 00e9d33e7826d6ab64639023e8939a74397ab044..a2fb8aebba817ab78c09d9f0eef2ae214e3c7f27 100644 (file)
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
+### Changed
+
+- Improve benchmarks: add IO intensive task workload, add task size option, integrate into eslint.
+
 ## [2.3.4] - 2022-10-17
 
 ### Added
index f78500f773032e33411ffdf820d1e3e582cc902c..34ebb788c0cd90341e9264cc1cb83b19f3c7568f 100755 (executable)
@@ -1,20 +1,30 @@
 #!/usr/bin/env bash
 
-### The -t argument is needed to specify the type of task that you want to benchmark.
-### Supported values are CPU_INTENSIVE
+### The -t argument permit to specify the type of task that you want to benchmark.
+### The -s argument permit to specify the size of task that you want to benchmark.
+### Supported values are CPU_INTENSIVE, IO_INTENSIVE
 
 taskType='CPU_INTENSIVE'
-while getopts t: flag
+taskSize=5000
+while getopts "t:s:h" option
 do
-  case "${flag}" in
+  case "${option}" in
     t)
       taskType=${OPTARG}
       ;;
+    s)
+      taskSize=${OPTARG}
+      ;;
+    *|h)
+      echo "Usage: $0 [-t taskType] [-s taskSize]"
+      exit 1
+      ;;
   esac
 done
 
-echo 'Running bench for task type:' $taskType
-export TASK_TYPE=$taskType
+echo 'Running benchmarks for task type:' ${taskType} 'and task size:' ${taskSize}
+export TASK_TYPE=${taskType}
+export TASK_SIZE=${taskSize}
 # Execute bench
 export NODE_ENV=production
 export POOL_SIZE=10
index 61681dab8efa1567d7525094ad20d6bff64d0315..f31bb0bb0f851a0653550f6bdb9257881552616f 100644 (file)
@@ -5,7 +5,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 const piscina = new Piscina({
@@ -21,6 +22,7 @@ async function run () {
     promises.push(piscina.run(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index f466d28a3cbfe7e83c8914851cfa3897d9cf6dc5..fe2a158f7f15674f4b96ba5cbc03a040304e26ad 100644 (file)
@@ -5,7 +5,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 const dynamicPool = new DynamicThreadPool(
@@ -20,6 +21,7 @@ async function run () {
     promises.push(dynamicPool.execute(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index fd0b7bd1caecb76937f27d8195ce2e8e49197f01..f6e32414e60872724d113c0baa81ca7b6b605995 100644 (file)
@@ -8,7 +8,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 const pool = new DynamicPool(size)
@@ -24,6 +25,7 @@ async function run () {
     )
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index 6b860d5f1ad9f959eeece37d54c1b0b3d364b5ad..11a2b2d496af35f22f1ed64f3e14fb084ac2f56a 100644 (file)
@@ -5,7 +5,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 const workerNodes = new WorkerNodes(
@@ -23,6 +24,7 @@ async function run () {
     promises.push(workerNodes.call.functionToBench(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index 9b9269362c52a55b2718ba3f77c2e42683abafc2..d168633f32e89f46dd85e74c6313ba89a09e624f 100644 (file)
@@ -3,7 +3,7 @@ const workerpool = require('workerpool')
 // FINISH IMPORT LIBRARIES
 const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
-const dataArray = ['MYBENCH', process.env['TASK_TYPE']]
+const dataArray = ['MYBENCH', process.env.TASK_TYPE, process.env.TASK_SIZE]
 
 const workerPool = workerpool.pool(
   './workers/workerpool/function-to-bench-worker.js',
@@ -20,6 +20,7 @@ async function run () {
     promises.push(workerPool.exec('functionToBench', dataArray))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index 287d8a6f8948a5f164faaf20e784bf1dc6b66bbe..2ab167aa6dc8760f35bc2e4c35b3e219f097a482 100644 (file)
@@ -8,7 +8,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 async function run () {
@@ -20,11 +21,12 @@ async function run () {
         data => {
           functionToBench(data)
         },
-        { data: data, ctx: { functionToBench } }
+        { data, ctx: { functionToBench } }
       )
     )
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index 861fe4f6b99662ca93d2a944d898f58c64f41b7a..b87857335d019ad015d7f59f7923d5e10d079f33 100644 (file)
@@ -5,7 +5,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 const piscina = new Piscina({
@@ -20,6 +21,7 @@ async function run () {
     promises.push(piscina.run(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index 28aa7e3ab4657baa2410f381af8ce54bd58076bb..38682040759adf3a8421a39fc1b70fbc2f5d1e0a 100644 (file)
@@ -5,7 +5,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 const fixedPool = new FixedThreadPool(
@@ -19,6 +20,7 @@ async function run () {
     promises.push(fixedPool.execute(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index eb316b5354902b231438345305089aea96fabcce..8a036fbd812ae2b148dac418b5e51ebd88d955e9 100644 (file)
@@ -4,7 +4,8 @@ const threadPool = require('./pool-threadwork')
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 async function run () {
@@ -13,6 +14,7 @@ async function run () {
     promises.push(threadPool.run(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index 58965d212c88e8e50acc70ada69c85afe4b470f5..2d4e7c2226118181b19e24537e236f3b35fd4529 100644 (file)
@@ -5,7 +5,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 const workerNodes = new WorkerNodes(
@@ -23,6 +24,7 @@ async function run () {
     promises.push(workerNodes.call.functionToBench(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index cf60a3660eb99bb0e5951e1235702da02853b486..95f44d0b5b35dc7849e0e069ea9460ba3a501720 100644 (file)
@@ -3,7 +3,7 @@ const workerpool = require('workerpool')
 // FINISH IMPORT LIBRARIES
 const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
-const dataArray = ['MYBENCH', process.env['TASK_TYPE']]
+const dataArray = ['MYBENCH', process.env.TASK_TYPE, process.env.TASK_SIZE]
 
 const workerPool = workerpool.pool(
   './workers/workerpool/function-to-bench-worker.js',
@@ -20,6 +20,7 @@ async function run () {
     promises.push(workerPool.exec('functionToBench', dataArray))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index b9054db22654b51d16ade84f9adf4c62aca192f4..7ecc7e12b89059b3878f443c3f594cb5c69f1773 100644 (file)
@@ -1,9 +1,18 @@
+const fs = require('fs')
+
+const TaskTypes = {
+  CPU_INTENSIVE: 'CPU_INTENSIVE',
+  IO_INTENSIVE: 'IO_INTENSIVE'
+}
+
 module.exports = function (data) {
+  console.log('functionToBench', data)
   data = data || {}
-  data.taskType = data.taskType || 'CPU_INTENSIVE'
+  data.taskType = data.taskType || TaskTypes.CPU_INTENSIVE
   data.taskSize = data.taskSize || 5000
+  const benchmarksFilePath = '/tmp/poolifier-benchmarks'
   switch (data.taskType) {
-    case 'CPU_INTENSIVE':
+    case TaskTypes.CPU_INTENSIVE:
       // CPU intensive task
       for (let i = 0; i < data.taskSize; i++) {
         const o = {
@@ -12,6 +21,14 @@ module.exports = function (data) {
         JSON.stringify(o)
       }
       return { ok: 1 }
+    case TaskTypes.IO_INTENSIVE:
+      // IO intensive task
+      for (let i = 0; i < data.taskSize; i++) {
+        fs.writeFileSync(benchmarksFilePath, i.toString(), 'utf8')
+        fs.readFileSync(benchmarksFilePath, 'utf8')
+        fs.unlinkSync(benchmarksFilePath)
+      }
+      return { ok: 1 }
     default:
       throw new Error(`Unknown task type: ${data.taskType}`)
   }
index 5e5e04e33fe8fbc73905134eb16b596f58e1e28f..36baad1f4ea2414b39ca13e04a332e4e5966ad90 100644 (file)
@@ -6,4 +6,4 @@ const functionToBench = require('./functions/function-to-bench')
 // FINISH IMPORT FUNCTION TO BENCH
 const size = Number(process.env.POOL_SIZE)
 
-module.exports = new ThreadPool({ task: functionToBench, size: size })
+module.exports = new ThreadPool({ task: functionToBench, size })
index ded55b882a8e66cd9bfbf0c8367e2b8de6e6eb7a..398c38edb826e6661976183b1b80f5a3b75fbe88 100644 (file)
@@ -8,11 +8,12 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 const pool = new StaticPool({
-  size: size,
+  size,
   task: functionToBench
 })
 
@@ -22,6 +23,7 @@ async function run () {
     promises.push(pool.exec(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index 18a01cfd9492ec0b462d39550189fdaa9adbf9c5..5d7d64ed4925b5aa4da55214945260f17605a9ef 100644 (file)
@@ -5,7 +5,8 @@ const size = Number(process.env.POOL_SIZE)
 const iterations = Number(process.env.NUM_ITERATIONS)
 const data = {
   test: 'MYBENCH',
-  taskType: process.env['TASK_TYPE']
+  taskType: process.env.TASK_TYPE,
+  taskSize: process.env.TASK_SIZE
 }
 
 // Threads.js is not really a pool so we need to write few additional code
@@ -27,6 +28,7 @@ async function run () {
     promises.push(worker.exposedFunction(data))
   }
   await Promise.all(promises)
+  // eslint-disable-next-line no-process-exit
   process.exit()
 }
 
index 02f777f7d0d95c170cdc0642cbe593b5d2066161..a883ce438eb44be74200fd00791833be6935a9fd 100644 (file)
@@ -2,8 +2,12 @@
 const workerpool = require('workerpool')
 const functionToBench = require('../../functions/function-to-bench')
 
-function workerPoolWrapperFunctionToBench (testName, taskType) {
-  return functionToBench({ test: testName, taskType: taskType })
+function workerPoolWrapperFunctionToBench (testName, taskType, taskSize) {
+  return functionToBench({
+    test: testName,
+    taskType,
+    taskSize
+  })
 }
 
 workerpool.worker({
index 94c665a6ae88ee55e15575ff72fbcfd176751842..ed1bddebe0e17914992b26d982e477bf95e8e7bc 100644 (file)
@@ -12,7 +12,7 @@ const iterations = 1000
 for (let i = 1; i <= iterations; i++) {
   pool
     .execute({})
-    .then(res => {
+    .then(() => {
       resolved++
       if (resolved === iterations) {
         console.log('Time take is ' + (Date.now() - start))
index 07a57c3ef9c5fc9ff455586498294149bf14ebdb..2c36a7038695e4e4a8a10dae15bc0f748a4b3849 100644 (file)
@@ -10,7 +10,7 @@ const iterations = 1000
 for (let i = 1; i <= iterations; i++) {
   pool
     .execute({})
-    .then(res => {
+    .then(() => {
       resolved++
       if (resolved === iterations) {
         return console.log('Time take is ' + (Date.now() - start))
index 96b861c44bf2127f1d9d55c521cfb4e244590dc7..8b29e3becaf7d73b3f15c35afc8b4b8c2834deb4 100644 (file)
@@ -1,6 +1,6 @@
 import { join } from 'path'
 import { DynamicThreadPool, FixedThreadPool } from 'poolifier'
-import { MyData, MyResponse } from './worker'
+import type { MyData, MyResponse } from './worker'
 
 export const fixedPool = new FixedThreadPool<MyData, Promise<MyResponse>>(
   8,
index 3e59f3465db2269fbb4ed2827f3c048c6010a8b8..5bd1ad6569c212b560d3eb829352f8974417b4a3 100644 (file)
@@ -4,7 +4,7 @@ const { isMainThread } = require('worker_threads')
 
 const debug = false
 
-function yourFunction (data) {
+function yourFunction () {
   for (let i = 0; i <= 1000; i++) {
     const o = {
       a: i
index a0ad5d4c751f0cbd69d2e805b35e38bac24924ba..442a4745b053de18dd6689c1c7dd0e17d4e5e020 100644 (file)
@@ -8,6 +8,6 @@
     "strict": true,
     "importsNotUsedAsValues": "error"
   },
-  "include": ["src/**/*.ts"],
+  "include": ["**/*.ts"],
   "exclude": ["node_modules"]
 }