</div>
<h2 align="center">Node Thread Pool and Cluster Pool :arrow_double_up: :on:</h2>
+<h2 align="center">
+ <a href="https://ko-fi.com/Q5Q31D6QY">
+ <img alt="Ko-fi" src="https://ko-fi.com/img/githubbutton_sm.svg"></a>
+</h2>
<p align="center">
<a href="https://www.npmjs.com/package/poolifier">
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.
- [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:
| 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 |
'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'
--- /dev/null
+// 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()
--- /dev/null
+'use strict'
+const { expose } = require("threads/worker")
+const functionToBench = require('../../functions/function-to-bench')
+
+expose({
+ exposedFunction (data) {
+ return functionToBench(data)
+ }
+})