PROOF JavaScript is a Multi-Threaded language

Fireship · Beginner ·🔧 Backend Engineering ·2y ago

Key Takeaways

This video demonstrates how JavaScript can be used as a multi-threaded language using Node.js Worker Threads and browser Web Workers, showcasing the basics of parallelism and concurrency in JavaScript.

Full Transcript

JavaScript is often referred to as a high level single threaded garbage collected interpreted or just-in-time compiled prototype-based multi-paradigm Dynamic language with a non-blocking event Lube but what if we could change one of those words like single threaded to multi-threaded believe it or not we can actually do that thanks to workers in node.js and the web workers API in the browser in today's video I'll show you how to unlock massive performance gains by running multi-threaded JavaScript but before we do that let's talk about concurrency versus parallelism these terms sound similar and they're related but they're two very distinct Concepts normally JavaScript is a single threaded language which means it can only take advantage of one CPU core called the main thread however this one thread can execute code concurrently thanks to javascript's non-blocking event Loop for example when you have a time-consuming operation like a fetch call to an API that code gets executed off the main thread then when it completes it goes back to the main thread and executes a callback function a callback function is named that way for a reason it's literally like saying execute this code then call me back when you're done with concurrency you're doing multiple jobs that overlap over different time periods in no specific order it's kind of like a restaurant that only has one cook in the kitchen you might have something in the stove and in the oven and the microwave all at the same time but when it comes to Preparing a plate of food the chef can only handle one at a time but now let's talk about parallelism it's also all about doing things at the same time but instead it utilizes multiple CPU cores to run code that would otherwise block the main thread for the chef in the restaurant it's like having extra Cooks alongside him to prepare multiple plates of food at the same time in practice multi-threading is ideal when you have multiple CPU intensive jobs going at the same time like looping over a large array or processing a bunch of images at the same time would be CPU intensive what it's not very useful for though is i o intensive work like reading and writing to a database the file system or network communication because in those cases you're waiting for the disk or the network to supply the actual data and the CPU can't do a whole lot to speed that up so it's important to keep in mind that multi-threading doesn't just magically speed everything up it's just a way to distribute work across multiple CPU cores when the CPU is doing the heavy lifting his historically people have criticized JavaScript as a toy language in part because it was single threaded but it's actually been capable of multi-threading for many years there are libraries like Party Town that use web workers to run scripts in the background and that same API is also supported in Dino but what we're going to look at today is the workers API in node.js to follow along simply create an index.js file in your editor now before we get into workers I first want to simulate a CPU intensive task that would block the main thread let's imagine we have an array of jobs to simulate something that we need to compute in this case I'll just populate that array with the number one billion 100 times from there we'll create a nested for Loop that Loops over each one of those jobs then simply iterates from zero to one billion until it reaches the end totally pointless but it's good exercise for the CPU now let's go ahead and use the performance module to grab a timestamp before and after this code runs to measure the execution time now we can go ahead and open up the terminal run the node command and wait in my case it took over just 40 seconds to count to 100 billion and that's a lot faster than I could do it but not very impressive compared to a compiled language running on multiple threads however contrary to popular belief JavaScript is not slow when it's just in time compiled by V8 it actually performs way better than many other interpreted languages because V8 which is built with C plus compiles it to machine code before executing it performance will vary based on your machine and in my case I have an Intel I9 processor with eight physical cores but because it does hyper threading we technically have 16 cores to work with just a side note a core refers to the physical component of the CPU itself which can only execute one task at a time whereas a thread refers to a sequence of instructions that can be managed independently by the operating system scheduler there's a distinction to be made there but from a practical standpoint the amount of node.js workers you can run in parallel is equal to the available number of CPU cores which in this case is 16. now to keep this code organized I'm first going to create a new file called worker.js and we can simply move the loop that does the actual work into it the goal is to have the code in this file not run on the main thread we could actually combine all this code in a single file because the node worker module allows you to check if you're are actually on the main thread but I think it's a lot easier to reason about when you put your worker in a separate file and back in the main file I'll go ahead and import the worker class from the worker threads module then from there I'll create a function that takes the array of jobs as an argument and then also specify the number of concurrent workers or threads that we want to run in parallel from there I defined a helper function called chunkify that will take the initial array of jobs and then split it into an equal number of subarrays so that way each one of our workers is doing roughly the same amount of work like if we have a hundred jobs and four CPU cores each worker would get 25 jobs from there we can Loop over each one of those chunks and then instantiate a new worker by pointing it to the worker.js file that we just created now here's where things get interesting your workers can pass messages back and forth between the main thread after you instantiate a worker you'll need to pass the message telling it to get to work and that message can also include data which in this case would be a chunk of jobs from the initial array now let's go back into the worker file and see how we can receive that message by importing the parent port from the worker threads module we can receive that message from the main thread the message will contain the data we passed in from the main thread and allows us to execute a callback function to process that data on a completely separate thread which is automatically allocated by your machine now finally when the work is done you'll need to notify the main thread which is accomplished by calling post message with this method you can pass data back to the main thread or in this case we'll just simply tell it that we're done although you could just do process.exit here if you don't want to pass any data now the final step is to listen to messages on the main thread from the workers for each worker we'll set up a listener for the message at which point we'll know the worker has completed in real life though you'd likely want to collect the data from the worker and do something with it on the main thread you might also be wondering if threads can share data while they run and the answer is yes there's a channel called code with Ryan that has a great video about this called node.js is a serious thing now but I'm not going to get into it in this video because a long time ago I tried to synchronize data across threads in Python and I ended up with so many race conditions that the doctors had to amputate my leg but now it's time to find out if this showed results in any actual kind of performance gains the last thing I'll do here is use the node.js performance module to measure the amount of time it takes for all the workers to complete and now we're ready to fire up the V8 engine remember that first run on the main thread took 44 seconds so now let's go ahead and run two workers in parallel currently my CPU usage is at about five percent but that should change after we run this code we see a definite increase in utilization up to about 15 percent and then the total execution time was about 20 seconds roughly twice as fast as the initial run on the main thread and that's exactly what we would expect because we're now using two threads instead of one but now let's find out what happens when we give it some more juice with four workers as expected CPU usage goes up to about 30 percent and the execution time is Once Again cut in half to about 10 seconds let's go ahead and double it again to eight workers now this time CPU usage goes above 50 because that's half of our available threads and total execution time goes down to 6.2 seconds a definite increase but we're now starting to get some diminishing returns now finally let's go ahead and give it everything we've got with 16 work workers this time the CPU goes to 100 utilization and total execution time comes down to 4.7 seconds making it a total of 10 times faster than the initial run on the main thread now we could continue to add more workers like say a hundred but there will no longer be any increase in performance because there's no available CPU cores to use those threads everything on the entire machine is completely blocked now to finish up this video I want to show you a really cool trick related to threads while this video is playing right now go ahead and open up your browser Dev tools inside the console create a while loop with a condition of true and then inside the brackets just go ahead and do nothing I'll go ahead and give you a moment to do that because it's important to run this code while the video is playing remember the browser is also single threaded so when you run this code it will lock up the main thread and the page should become unresponsive and that means you'll be stuck on this video allowing me to achieve infinite watch time I can now tell you anything I want and you'll never be able to click away from this video [Music] and I'd like to take this opportunity to invite you to become a fireship pro member to learn how to do all kinds of other cool stuff with JavaScript thanks for watching and I will see you in the next one if you're still here that means your browser is probably Frozen and I apologize for that to fix it all you have to do is unplug your computer and then plug it right back in or you can right click on the browser Tab and close it because every tab has its own thread and if that doesn't work just leave me a comment below the video and I'll try to troubleshoot from there

Original Description

Learn the basics of parallelism and concurrency in JavaScript by experimenting with Node.js Worker Threads and browser Web Workers. #javascript #programming #computerscience Upgrade to Fireship PRO https://fireship.io/pro Node.js Worker Threads https://nodejs.org/api/worker_threads.html Check out @codewithryan https://youtu.be/_Im4_3Z1NxQ
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Beyond Fireship · Beyond Fireship · 32 of 42

1 Social Media Style Number Formatting in JS
Social Media Style Number Formatting in JS
Beyond Fireship
2 I used 3 different File System APIs in Node.js
I used 3 different File System APIs in Node.js
Beyond Fireship
3 Time is Relative, even in JavaScript
Time is Relative, even in JavaScript
Beyond Fireship
4 How to NOT Screw Up Firebase Environment Variables
How to NOT Screw Up Firebase Environment Variables
Beyond Fireship
5 How to make your JavaScript Bundle Smaller
How to make your JavaScript Bundle Smaller
Beyond Fireship
6 Subtle, yet Beautiful Scroll Animations
Subtle, yet Beautiful Scroll Animations
Beyond Fireship
7 Beyond Surreal? A closer look at NewSQL Relational Data
Beyond Surreal? A closer look at NewSQL Relational Data
Beyond Fireship
8 How to Build a Discord Bot
How to Build a Discord Bot
Beyond Fireship
9 How to make Eyeballs that Follow You Around
How to make Eyeballs that Follow You Around
Beyond Fireship
10 Reverse Engineer Google’s NASA Dart Easter Egg with CSS
Reverse Engineer Google’s NASA Dart Easter Egg with CSS
Beyond Fireship
11 Generate Images Programmatically on the Edge
Generate Images Programmatically on the Edge
Beyond Fireship
12 WTF are all these config files for?
WTF are all these config files for?
Beyond Fireship
13 NEW Firebase Features Just Dropped
NEW Firebase Features Just Dropped
Beyond Fireship
14 Next.js 13 - The Basics
Next.js 13 - The Basics
Beyond Fireship
15 Make Crazy Art with the NEW OpenAI Dall-e API
Make Crazy Art with the NEW OpenAI Dall-e API
Beyond Fireship
16 How to Setup Node.js with TypeScript in 2023
How to Setup Node.js with TypeScript in 2023
Beyond Fireship
17 Dramatically improve website speed with Partytown
Dramatically improve website speed with Partytown
Beyond Fireship
18 The easiest realtime app I’ve ever built
The easiest realtime app I’ve ever built
Beyond Fireship
19 10 Rendering Patterns for Web Apps
10 Rendering Patterns for Web Apps
Beyond Fireship
20 You don't need Node to use NPM packages
You don't need Node to use NPM packages
Beyond Fireship
21 Sorting Algorithms Explained Visually
Sorting Algorithms Explained Visually
Beyond Fireship
22 ChatGPT Official API First Look
ChatGPT Official API First Look
Beyond Fireship
23 I built an image search engine
I built an image search engine
Beyond Fireship
24 Industrial-scale Web Scraping with AI & Proxy Networks
Industrial-scale Web Scraping with AI & Proxy Networks
Beyond Fireship
25 Next.js Server Actions...  5 awesome things you can do
Next.js Server Actions... 5 awesome things you can do
Beyond Fireship
26 The ultimate guide to web performance
The ultimate guide to web performance
Beyond Fireship
27 I built a fullstack PaLM AI app in just 2 minutes
I built a fullstack PaLM AI app in just 2 minutes
Beyond Fireship
28 I tried 8 different Postgres ORMs
I tried 8 different Postgres ORMs
Fireship
29 I built a *streaming* AI chat app
I built a *streaming* AI chat app
Fireship
30 React VS Svelte...10 Examples
React VS Svelte...10 Examples
Fireship
31 How GitHub Actions 10x my productivity
How GitHub Actions 10x my productivity
Fireship
PROOF JavaScript is a Multi-Threaded language
PROOF JavaScript is a Multi-Threaded language
Fireship
33 Mind-blowing page animations are easy now... View Transitions API first look
Mind-blowing page animations are easy now... View Transitions API first look
Fireship
34 I built an Apple Vision Pro app... visionOS tutorial
I built an Apple Vision Pro app... visionOS tutorial
Fireship
35 This UI component library is mind-blowing
This UI component library is mind-blowing
Fireship
36 How I deploy serverless containers for free
How I deploy serverless containers for free
Fireship
37 GitHub Copilot now controls your command line...
GitHub Copilot now controls your command line...
Fireship
38 Build better payment forms using new “embedded” Stripe Checkout
Build better payment forms using new “embedded” Stripe Checkout
Fireship
39 Does Deno 2 really uncomplicate JavaScript?
Does Deno 2 really uncomplicate JavaScript?
Fireship
40 JavaScript performance is weird... Write scientifically faster code with benchmarking
JavaScript performance is weird... Write scientifically faster code with benchmarking
Fireship
41 Is Next.js 15 any good? "use cache" API first look
Is Next.js 15 any good? "use cache" API first look
Beyond Fireship
42 I built a DeepSeek R1 powered VS Code extension…
I built a DeepSeek R1 powered VS Code extension…
Fireship

This video teaches the basics of parallelism and concurrency in JavaScript using Node.js Worker Threads and browser Web Workers, demonstrating how to write multi-threaded JavaScript code and optimize it for CPU-intensive jobs.

Key Takeaways
  1. Create an index.js file in the editor
  2. Simulate a CPU-intensive task using a nested for loop
  3. Use the performance module to measure execution time
  4. Run the node command in the terminal
  5. Create a new file called worker.js
  6. Move the loop that does the actual work into worker.js
  7. Import the worker class from the worker_threads module
  8. Create a function that takes the array of jobs as an argument and specifies the number of concurrent workers or threads
  9. Define a helper function called chunkify to split the initial array of jobs into subarrays
  10. Use Node.js performance module to measure execution time
💡 JavaScript can be used as a multi-threaded language using Node.js Worker Threads and browser Web Workers, allowing for concurrent programming and parallel processing to speed up execution time.

Related AI Lessons

Up next
This Cop Was Held Accountable For His Brutality! #police #lawyer
Hampton Law
Watch →