Skip to content

How Threads Works in NodeJS

References

worker.mjs

import { parentPort } from "worker_threads";

// O(2^n)
const fibonacci = n => {
	if (n <= 1) {
		return n;
	}
	return fibonacci(n - 1) + fibonacci(n - 2);
};

const result = fibonacci(42);

parentPort.postMessage(result);

threads.mjs

import { Worker } from "worker_threads";

function runWorker() {
	return new Promise((resolve, reject) => {
		const worker = new Worker("./worker.mjs");
		worker.on("message", resolve);
		worker.on("error", reject);
		worker.on("exit", code => {
			if (code !== 0) reject(new Error(`Worker stopped with code ${code}`));
		});
	});
}

async function runMultipleWorkers(numWorkers) {
	const promises = [];
	for (let i = 0; i < numWorkers; i++) {
		promises.push(runWorker());
	}
	return Promise.all(promises);
}

runMultipleWorkers(8)
	.then(results => {
		results.forEach((result, index) => {
			console.log(`Worker ${index + 1} result: ${result}`);
		});
	})
	.catch(err => {
		console.error(err);
	});

console.log("Meanwhile, the main program continues to run!");

// node threads.mjs
// Meanwhile, the main program continues to run!
// Worker 1 result: 267914296
// Worker 2 result: 267914296
// Worker 3 result: 267914296
// Worker 4 result: 267914296
// Worker 5 result: 267914296
// Worker 6 result: 267914296
// Worker 7 result: 267914296
// Worker 8 result: 267914296
// thread pool default is 4
import { pbkdf2 } from "crypto";

const start = Date.now();

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("1: ", Date.now() - start);
});

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("2: ", Date.now() - start);
});

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("3: ", Date.now() - start);
});

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("4: ", Date.now() - start);
});

// will wait until one thread is free
pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("5: ", Date.now() - start);
});

// node example-1.mjs
// 1:  350
// 2:  368
// 3:  377
// 4:  385
// 5:  844
process.env.UV_THREADPOOL_SIZE = 2;

import { pbkdf2 } from "crypto";

const start = Date.now();

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("1: ", Date.now() - start);
});

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("2: ", Date.now() - start);
});

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("3: ", Date.now() - start);
});

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("4: ", Date.now() - start);
});

pbkdf2("a", "b", 100000, 512, "sha512", () => {
	console.log("5: ", Date.now() - start);
});

// node example-2.mjs
// 1:  394
// 4:  408
// 2:  415
// 3:  425
// 5:  847
import { request } from "https";
const start = Date.now();

const makeRequest = () => {
	request("https://youtube.com", response => {
		response.on("data", () => {});
		response.on("end", () => {
			console.log(Date.now() - start);
		});
	}).end();
};

makeRequest();
makeRequest();
makeRequest();
makeRequest();
makeRequest();
makeRequest();

// node example-3.mjs
// 283
// 290
// 291
// 291
// 292
// 293
import { createInterface } from "readline";

function isSorted(arr) {
	for (let i = 1; i < arr.length; i++) {
		if (arr[i - 1] > arr[i]) {
			return false;
		}
	}
	return true;
}

function shuffle(arr) {
	for (let i = arr.length - 1; i > 0; i--) {
		const j = Math.floor(Math.random() * (i + 1));
		[arr[i], arr[j]] = [arr[j], arr[i]];
	}
}

// O(n * n!)
// the dumbest way to sort array
function monkeySort(array) {
	while (!isSorted(array)) {
		shuffle(array);
	}
	return array;
}

const rl = createInterface({
	input: process.stdin,
	output: process.stdout,
});

// O(2^n)
const fibonacci = n => {
	if (n <= 1) {
		return n;
	}
	return fibonacci(n - 1) + fibonacci(n - 2);
};

const generateRandomArray = size => {
	const array = [];
	for (let i = 0; i < size; i++) {
		array.push(Math.floor(Math.random() * 100));
	}
	return array;
};

rl.question("Enter size of the array: ", size => {
	const array = generateRandomArray(size);

	console.log("Original array: ", array);
	const start = Date.now();

	const sortedArray = monkeySort(array);
	console.log("Sorted array: ", sortedArray);
	console.log("Time monkeySort: ", Date.now() - start);

	const n = 42;
	console.log("The Nth number in the fibonacci sequence is: ", fibonacci(n));
	console.log(`Time fibonacci(${n}): `, Date.now() - start);

	rl.close();
});

// node example-4.mjs
// Enter size of the array: 10
// Original array:  [
//    3, 68, 47,  4, 62,
//   54, 38, 49, 10, 46
// ]
// Sorted array:  [
//    3,  4, 10, 38, 46,
//   47, 49, 54, 62, 68
// ]
// Time monkeySort:  147
// The Nth number in the fibonacci sequence is:  267914296
// Time fibonacci(42):  3762
import { request } from "https";
import { pbkdf2 } from "crypto";
import { readFile } from "fs";
const start = Date.now();

const makeHash = () => {
	pbkdf2("a", "b", 100000, 512, "sha512", () => {
		console.log("Hash: ", Date.now() - start);
	});
};

const makeRequest = () => {
	request("https://youtube.com", response => {
		response.on("data", () => {});
		response.on("end", () => {
			console.log(Date.now() - start);
		});
	}).end();
};

makeRequest();
makeHash();
makeHash();
makeHash();

readFile("example-1.js", "utf-8", () => {
	console.log("FS: ", Date.now() - start);
});

// node example-5.mjs
// FS:  54
// 281
// Hash:  424
// Hash:  431
// Hash:  438