Threadjs benchmarks (#230)
authorAlessandro Pio Ardizio <alessandroardizio94@gmail.com>
Tue, 23 Feb 2021 13:51:38 +0000 (14:51 +0100)
committerGitHub <noreply@github.com>
Tue, 23 Feb 2021 13:51:38 +0000 (14:51 +0100)
* Add threadjs to our benchmarks and re-run

* documentation

* Center support button

* Center support button

* Center support button

README.md
benchmarks/README.md
benchmarks/versus-external-pools/BENCH-100000.MD
benchmarks/versus-external-pools/bench.sh
benchmarks/versus-external-pools/threadjs.js [new file with mode: 0644]
benchmarks/versus-external-pools/workers/threadjs/function-to-bench-worker.js [new file with mode: 0644]

index 83ec2122c2bf11bc4aab12c28bf50676f88b5fcd..ce026b148412eb6e445db1b6d6f53775af7bed2d 100644 (file)
--- a/README.md
+++ b/README.md
@@ -3,6 +3,10 @@
 </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">
@@ -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.  
index c488a23e742de1818b3c69144301230c4764a4e2..d368e86121a2d57cfcac3ae825100ff1d0022360 100644 (file)
@@ -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:
 
index 0baa4b4fe849e5622fc7504efca01e3320ead1dc..180a1634bca4fa84f2d62c179d1d17d77eb6a1a4 100644 (file)
@@ -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 |
index 8b361aa4101b3977581d946329bd167d2496cdf9..cf17aabef6ea9196e53d210d4cfd10f8a43ec250 100755 (executable)
@@ -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 (file)
index 0000000..a70692b
--- /dev/null
@@ -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 (file)
index 0000000..81f2c58
--- /dev/null
@@ -0,0 +1,9 @@
+'use strict'
+const { expose } = require("threads/worker")
+const functionToBench = require('../../functions/function-to-bench')
+
+expose({
+  exposedFunction (data) {
+    return functionToBench(data)
+  }
+})