To compare poolifier pools performance vs other pools performance we chose to use [hyperfine](https://github.com/sharkdp/hyperfine).
We chose to use this tool because it allows to run isolated Node.js processes so that each pool does not impact each other.
-We will add more details on each function that we benchmark.
-
Those are our results:
-- CPU Intensive task with 100k operations submitted to each pool [BENCH-100000.MD](./versus-external-pools/BENCH-100000.MD)
+- CPU Intensive task with 100k operations submitted to each pool [BENCH-100000.MD](./versus-external-pools/BENCH-100000.MD).
+This benchmark ran on a MacBook Pro 2015, 2,2 GHz Intel Core i7 quad-core, 16 GB 1600 MHz DDR3
## How to run benchmarks
- [Install hyperfine](https://github.com/sharkdp/hyperfine#installation)
- Run the `./bench.sh` into the `versus-external-pools` folder
+
+> :warning: **Please be sure to use a quite PC when you run the benchmarks**
| Command | Mean [s] | Min [s] | Max [s] | Relative |
|:---|---:|---:|---:|---:|
-| `node static-suchmokuo-node-worker-threads-pool.js` | 47.473 ± 1.241 | 44.031 | 48.331 | 1.05 ± 0.03 |
-| `node dynamic-poolifier.js` | 45.368 ± 0.173 | 45.028 | 45.595 | 1.00 |
-| `node piscina.js` | 48.502 ± 0.390 | 47.896 | 49.362 | 1.07 ± 0.01 |
+| `node static-suchmokuo-node-worker-threads-pool.js` | 50.403 ± 1.280 | 46.822 | 51.241 | 1.04 ± 0.04 |
+| `node dynamic-suchmokuo-node-worker-threads-pool.js` | 62.664 ± 0.158 | 62.329 | 62.852 | 1.29 ± 0.03 |
+| `node dynamic-poolifier.js` | 48.517 ± 1.233 | 47.662 | 51.249 | 1.00 |
+| `node fixed-poolifier.js` | 48.539 ± 1.247 | 47.848 | 52.056 | 1.00 ± 0.04 |
+| `node dynamic-piscina.js` | 51.187 ± 0.184 | 50.986 | 51.579 | 1.06 ± 0.03 |
+| `node fixed-piscina.js` | 51.259 ± 0.087 | 51.114 | 51.404 | 1.06 ± 0.03 |
-export NODE_ENV=production
-
-# Execute bench
-# export POOL_SIZE=8
-# export NUM_ITERATIONS=10000
-# hyperfine --export-markdown BENCH-10000.MD --min-runs 10 \
-# 'node dynamic-poolifier.js' \
-# 'node dynamic-suchmokuo-node-worker-threads-pool.js' \
-# 'node fixed-poolifier.js' \
-# 'node static-suchmokuo-node-worker-threads-pool.js' \
-# 'node piscina.js'
+### The -t argument is needed to specify the type of task that you want to benchmark.
+### Supported values are CPU_INTENSIVE
-# echo "Sleeping...."
-# sleep 60
+taskType='CPU_INTENSIVE'
+while getopts t: flag
+do
+ case "${flag}" in
+ t) taskType=${OPTARG};;
+ esac
+done
+echo 'Running bench for task type:' $taskType
+export TASK_TYPE=$taskType
+# Execute bench
+export NODE_ENV=production
export POOL_SIZE=10
export NUM_ITERATIONS=100000
hyperfine --export-markdown BENCH-100000.MD --min-runs 10 \
'node static-suchmokuo-node-worker-threads-pool.js' \
+ 'node dynamic-suchmokuo-node-worker-threads-pool.js' \
'node dynamic-poolifier.js' \
- 'node piscina.js'
-
-# export POOL_SIZE=8
-# export NUM_ITERATIONS=50000
-# hyperfine --export-markdown BENCH-50000.MD --min-runs 10 \
-# 'node dynamic-poolifier.js' \
-# 'node dynamic-suchmokuo-node-worker-threads-pool.js' \
-# 'node fixed-poolifier.js' \
-# 'node static-suchmokuo-node-worker-threads-pool.js' \
-# 'node piscina.js'
-
-# export NUM_ITERATIONS=100000
-# hyperfine --export-markdown BENCH-50000.MD --min-runs 20 \
-# 'node dynamic-poolifier.js' \
-# 'node static-suchmokuo-node-worker-threads-pool.js' \
-# 'node piscina.js'
-
+ 'node fixed-poolifier.js' \
+ 'node dynamic-piscina.js' \
+ 'node fixed-piscina.js'
const size = process.env.POOL_SIZE
const iterations = process.env.NUM_ITERATIONS
const data = {
- test: 'MYBENCH'
+ test: 'MYBENCH',
+ taskType: process.env['TASK_TYPE']
}
const piscina = new Piscina({
- filename: './workers/piscina/json-stringify.worker.js',
+ filename: './workers/piscina/function-to-bench-worker.js',
minThreads: Number(size),
maxThreads: size * 3,
idleTimeout: 1000 * 60 // this is the same as poolifier default
const size = process.env.POOL_SIZE
const iterations = process.env.NUM_ITERATIONS
const data = {
- test: 'MYBENCH'
+ test: 'MYBENCH',
+ taskType: process.env['TASK_TYPE']
}
const dynamicPool = new DynamicThreadPool(
size,
size * 3,
- './workers/poolifier/json-stringify.worker.js',
+ './workers/poolifier/function-to-bench-worker.js',
{
maxTasks: 10000
}
const { DynamicPool, StaticPool } = require('node-worker-threads-pool')
// FINISH IMPORT LIBRARIES
// IMPORT FUNCTION TO BENCH
-const functionToBench = require('./functions/json-stringify')
+const functionToBench = require('./functions/function-to-bench')
// FINISH IMPORT FUNCTION TO BENCH
const size = process.env.POOL_SIZE
const iterations = process.env.NUM_ITERATIONS
const data = {
- test: 'MYBENCH'
+ test: 'MYBENCH',
+ taskType: process.env['TASK_TYPE']
}
const pool = new DynamicPool(Number(size))
--- /dev/null
+// IMPORT LIBRARIES
+const Piscina = require('piscina')
+// FINISH IMPORT LIBRARIES
+const size = process.env.POOL_SIZE
+const iterations = process.env.NUM_ITERATIONS
+const data = {
+ test: 'MYBENCH',
+ taskType: process.env['TASK_TYPE']
+}
+
+const piscina = new Piscina({
+ filename: './workers/piscina/function-to-bench-worker.js',
+ minThreads: Number(size),
+ idleTimeout: 1000 * 60 // this is the same as poolifier default
+})
+
+async function run () {
+ const promises = []
+ for (let i = 0; i < iterations; i++) {
+ promises.push(piscina.runTask(data))
+ }
+ await Promise.all(promises)
+ process.exit()
+}
+
+run()
const size = process.env.POOL_SIZE
const iterations = process.env.NUM_ITERATIONS
const data = {
- test: 'MYBENCH'
+ test: 'MYBENCH',
+ taskType: process.env['TASK_TYPE']
}
const fixedPool = new FixedThreadPool(
size,
- './workers/poolifier/json-stringify.worker.js',
+ './workers/poolifier/function-to-bench-worker.js',
{
maxTasks: 100000
}
--- /dev/null
+module.exports = function (data) {
+ if ( data.taskType === 'CPU_INTENSIVE' ) {
+ // CPU Intensive task
+ for (let i = 0; i <= 5000; i++) {
+ const o = {
+ a: i
+ }
+ JSON.stringify(o)
+ }
+ return { ok: 1 }
+ } else {
+ throw new Error('Please specify the task type')
+ }
+}
+++ /dev/null
-module.exports = function (data) {
- for (let i = 0; i <= 5000; i++) {
- const o = {
- a: i
- }
- JSON.stringify(o)
- }
- // console.log('STRINGIFY FUNCTION FINISHED')
- return { ok: 1 }
-}
"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="
},
"poolifier": {
- "version": "2.0.0-beta.6",
- "resolved": "https://registry.npmjs.org/poolifier/-/poolifier-2.0.0-beta.6.tgz",
- "integrity": "sha512-n+IumaVITBY1/UD4gC4e6uXHlBIgy2+AKeX4BmhEP4phIM6DCYBYBRuVk5lk8LlXKiO8HFrQ3WXHzCpubqWyqA=="
+ "version": "2.0.0-beta.7",
+ "resolved": "https://registry.npmjs.org/poolifier/-/poolifier-2.0.0-beta.7.tgz",
+ "integrity": "sha512-ZGrwPJdCRlQu3oIIAZBZQgrjOPzLUU+GNpPP4KpvVplL+XeDYHzIqtiss9M/3rYgmFuus6DiUd5JFWqnb5dtLg=="
},
"symbol-observable": {
"version": "1.2.0",
const { DynamicPool, StaticPool } = require('node-worker-threads-pool')
// FINISH IMPORT LIBRARIES
// IMPORT FUNCTION TO BENCH
-const functionToBench = require('./functions/json-stringify')
+const functionToBench = require('./functions/function-to-bench')
// FINISH IMPORT FUNCTION TO BENCH
const size = process.env.POOL_SIZE
const iterations = process.env.NUM_ITERATIONS
const data = {
- test: 'MYBENCH'
+ test: 'MYBENCH',
+ taskType: process.env['TASK_TYPE']
}
const pool = new StaticPool({
--- /dev/null
+'use strict'
+const functionToBench = require('../../functions/function-to-bench')
+module.exports = functionToBench
+++ /dev/null
-'use strict'
-const jsonStringify = require('../../functions/json-stringify')
-module.exports = jsonStringify
--- /dev/null
+'use strict'
+const { ThreadWorker } = require('poolifier')
+const functionToBench = require('../../functions/function-to-bench')
+module.exports = new ThreadWorker(functionToBench)
+++ /dev/null
-'use strict'
-const { ThreadWorker } = require('poolifier')
-const jsonStringify = require('../../functions/json-stringify')
-module.exports = new ThreadWorker(jsonStringify)