From 75876e4c557ce7fcb132929185777e535e244d0d Mon Sep 17 00:00:00 2001 From: Alessandro Pio Ardizio Date: Tue, 23 Feb 2021 14:51:38 +0100 Subject: [PATCH] Threadjs benchmarks (#230) * Add threadjs to our benchmarks and re-run * documentation * Center support button * Center support button * Center support button --- README.md | 8 ++++- benchmarks/README.md | 1 + .../versus-external-pools/BENCH-100000.MD | 13 ++++---- benchmarks/versus-external-pools/bench.sh | 3 +- benchmarks/versus-external-pools/threadjs.js | 32 +++++++++++++++++++ .../threadjs/function-to-bench-worker.js | 9 ++++++ 6 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 benchmarks/versus-external-pools/threadjs.js create mode 100644 benchmarks/versus-external-pools/workers/threadjs/function-to-bench-worker.js diff --git a/README.md b/README.md index 83ec2122..ce026b14 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@

Node Thread Pool and Cluster Pool :arrow_double_up: :on:

+

+ + Ko-fi +

@@ -199,7 +203,9 @@ We already have a bench folder where you can find some comparisons. Thread pools are built on top of Node.js [worker-threads](https://nodejs.org/api/worker_threads.html#worker_threads_worker_threads) module. **Cluster pools** (FixedClusterPool and DynamicClusterPool) are suggested to run I/O intensive tasks, again you can still run CPU intensive tasks into cluster pools, but performance enhancement is expected to be minimal. -Cluster pools are built on top of Node.js [cluster](https://nodejs.org/api/cluster.html) module. +Cluster pools are built on top of Node.js [cluster](https://nodejs.org/api/cluster.html) module. + +**Remember** that some Node.js tasks are execute by Node.js into the libuv worker pool at process level as explained [here](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/#what-code-runs-on-the-worker-pool). To choose your pool consider that with a FixedThreadPool/FixedClusterPool or a DynamicThreadPool/DynamicClusterPool (in this case is important the min parameter passed to the constructor) your application memory footprint will increase. Increasing the memory footprint, your application will be ready to accept more tasks, but during idle time your application will consume more memory. diff --git a/benchmarks/README.md b/benchmarks/README.md index c488a23e..d368e861 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -15,6 +15,7 @@ External pools with which we compared the poolifier results: - [piscina](https://github.com/piscinajs/piscina) - [SUCHMOKUO/node-worker-threads-pool](https://github.com/SUCHMOKUO/node-worker-threads-pool) +- [threads.js](https://github.com/andywer/threads.js/) Those are our results: diff --git a/benchmarks/versus-external-pools/BENCH-100000.MD b/benchmarks/versus-external-pools/BENCH-100000.MD index 0baa4b4f..180a1634 100644 --- a/benchmarks/versus-external-pools/BENCH-100000.MD +++ b/benchmarks/versus-external-pools/BENCH-100000.MD @@ -1,8 +1,9 @@ | Command | Mean [s] | Min [s] | Max [s] | Relative | |:---|---:|---:|---:|---:| -| `node dynamic-piscina.js` | 48.207 ± 0.383 | 47.715 | 49.117 | 1.06 ± 0.01 | -| `node fixed-piscina.js` | 48.398 ± 0.146 | 48.194 | 48.626 | 1.07 ± 0.01 | -| `node dynamic-poolifier.js` | 45.319 ± 0.813 | 44.667 | 47.532 | 1.00 ± 0.02 | -| `node fixed-poolifier.js` | 45.308 ± 0.194 | 44.997 | 45.648 | 1.00 | -| `node static-suchmokuo-node-worker-threads-pool.js` | 47.804 ± 0.188 | 47.431 | 47.993 | 1.06 ± 0.01 | -| `node dynamic-suchmokuo-node-worker-threads-pool.js` | 61.837 ± 2.315 | 59.423 | 64.619 | 1.36 ± 0.05 | +| `node dynamic-piscina.js` | 47.192 ± 0.607 | 46.774 | 48.804 | 1.07 ± 0.01 | +| `node fixed-piscina.js` | 47.046 ± 0.112 | 46.823 | 47.178 | 1.07 ± 0.00 | +| `node dynamic-poolifier.js` | 44.301 ± 0.989 | 43.718 | 46.994 | 1.00 ± 0.02 | +| `node fixed-poolifier.js` | 44.115 ± 0.174 | 43.843 | 44.510 | 1.00 | +| `node static-suchmokuo-node-worker-threads-pool.js` | 48.282 ± 1.857 | 46.361 | 50.268 | 1.09 ± 0.04 | +| `node dynamic-suchmokuo-node-worker-threads-pool.js` | 60.111 ± 2.401 | 57.752 | 63.011 | 1.36 ± 0.05 | +| `node threadjs.js` | 131.412 ± 4.210 | 122.872 | 138.506 | 2.98 ± 0.10 | diff --git a/benchmarks/versus-external-pools/bench.sh b/benchmarks/versus-external-pools/bench.sh index 8b361aa4..cf17aabe 100755 --- a/benchmarks/versus-external-pools/bench.sh +++ b/benchmarks/versus-external-pools/bench.sh @@ -22,4 +22,5 @@ hyperfine --export-markdown BENCH-100000.MD --min-runs 10 \ 'node dynamic-poolifier.js' \ 'node fixed-poolifier.js' \ 'node static-suchmokuo-node-worker-threads-pool.js' \ - 'node dynamic-suchmokuo-node-worker-threads-pool.js' + 'node dynamic-suchmokuo-node-worker-threads-pool.js' \ + 'node threadjs.js' diff --git a/benchmarks/versus-external-pools/threadjs.js b/benchmarks/versus-external-pools/threadjs.js new file mode 100644 index 00000000..a70692bb --- /dev/null +++ b/benchmarks/versus-external-pools/threadjs.js @@ -0,0 +1,32 @@ +// IMPORT LIBRARIES +const { spawn, Thread, Worker } = require('threads') +// FINISH IMPORT LIBRARIES +const size = process.env.POOL_SIZE +const iterations = process.env.NUM_ITERATIONS +const data = { + test: 'MYBENCH', + taskType: process.env['TASK_TYPE'] +} + +// Threads.js is not really a pool so we need to write few additional code +const workers = [] +async function poolify () { + for (let i = 0; i < size ; i++ ){ + const worker = await spawn(new Worker("./workers/threadjs/function-to-bench-worker.js")) + workers.push(worker) + } +} + + +async function run () { + await poolify() + const promises = [] + for (let i = 0; i < iterations; i++) { + const worker = workers[(i % size)] + promises.push(worker.exposedFunction(data)) + } + await Promise.all(promises) + process.exit() +} + +run() diff --git a/benchmarks/versus-external-pools/workers/threadjs/function-to-bench-worker.js b/benchmarks/versus-external-pools/workers/threadjs/function-to-bench-worker.js new file mode 100644 index 00000000..81f2c58e --- /dev/null +++ b/benchmarks/versus-external-pools/workers/threadjs/function-to-bench-worker.js @@ -0,0 +1,9 @@ +'use strict' +const { expose } = require("threads/worker") +const functionToBench = require('../../functions/function-to-bench') + +expose({ + exposedFunction (data) { + return functionToBench(data) + } +}) -- 2.34.1