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