JavaScript performance is weird... Write scientifically faster code with benchmarking
- Views
- 256K
- 255,926
- Outlier
- ×0.8
- Median 316K
- Length
- 8:20
- Published
- Oct 30, 2024
- Wednesday
- Comments
- 341
- 11.2K likes
Script
How it's written
- Words
- 1,848
- Words a minute
- 221
- Reading time
- 8 min
- Segments
- 6
The hook
0:00–0:26what you're looking at here are the five rules of programming written by the legendary programmer Rob Pike who programmed the go programming language the first rule of programming is do not talk about programming the second rule of programming is to measure don't tune for Speed until you've measured and even then don't unless one part of the code overwhelms the rest this Echoes another legendary programmer Donald canth who offered similar advice when he said premature optimization is the root of all evil even my dad would tell me
Structure
what you're looking at here are the five rules of programming written by the legendary programmer Rob Pike who programmed the go programming language the first rule of programming is do not talk about programming the second rule of programming is to measure don't tune for Speed until you've measured and even then don't unless one part of the code overwhelms the rest this Echoes another legendary programmer Donald canth who offered similar advice when he said premature optimization is the root of all evil even my dad would tell me measure twice cut once in programming there's a nearly Unlimited a number of ways to skin a cat but the way you write your code matters like as we'll see in JavaScript there's at least four different ways to Loop over an array and count its values but the performance of each technique varies dramatically in today's video I'll show you how to easily Benchmark your JavaScript code so you can scientifically measure its performance and avoid wasting time optimizing red herrings to help us make benchmarking extremely easy we're going to use the JavaScript runtime Dino which has a built-in benchmarking tool after playing around with it for a few days I was able to achieve some amazing things like I figured out how to make array includes 100,000 times faster I was able to write a sorting algorithm that outperforms the built-in array sort method in JavaScript and I figured out the fastest way to write a loop let's take a look at how Doo bench works at first you'll want to make sure you have Doo 2 installed and I also want to point out that this video is part of my full Dino course which is now officially in production and should be out around November 7th which will include about 25 videos and multiple projects the other thing I want to point out is that we're measuring JavaScript and its performance only on the doo runtime which under the
Watch from 0:00hood is powered by the V8 engine which also Powers all chromium browsers and no. JS however if you're looking to compare performance between different run times like node Dino and Bun I'd highly recommend this video from Anton Putra which puts all three of them to the test in a large scale Cloud environment but now let's jump into the code and answer the question what is the fastest way to Loop over an array in JavaScript well I know of at least four different ways to do it which I've represented in these four functions where the goal is to Loop over an array and then sum up the numbers in that array first up we've got the array for each method if you have an array one option is to use for each provide it with a callback function that mutates a variable that works but there is a cleaner way to do this with array reduce which also takes a callback function but also has an accumulated value is so there's no need to mutate that variable you'll see functional declarative code like this a lot in front-end projects like reactjs however the next option is to increment the sum using a regular four Loop in JavaScript you can create a four of Loop that will automatically iterate to the end of the array that's nice and readable but the traditional way to write a for Loop is to use this more explicit syntax where we have a variable of I that's incremented as we Loop over the array's length and that gives us four ways to solve the same problem but the big question is which one will perform the best well the first thing we'll do is create some testing data like in this case generate a large array with 100,000 elements in it and now finally this is where Doo bench comes in on the global Dino namespace you can call the bench method and then either provide it with a regular function to Benchmark or provide it with
Watch from 1:31an object so you can give each Benchmark a name and then the FN property will take a function which is the actual code that you want to run and measure in this file we'll use doench to set up a benchmark for each one of our functions it also helps to set up a baseline which would typically be your original code and in this case I'm going to set that as our traditional for Loop in Doo these benchmarks don't actually affect your runtime code but they act more like testing code and the way to execute the benchmarks is to open up the terminal and run the doench command followed by the file name it'll take a few seconds to run but it gives us this report that shows how many iterations of the function it was able to run per second and its average execution time as well as the best case and worst case performance but at a high level the most useful thing is just the summary that shows us which function is fastest and surprisingly the traditional for Loop is significantly faster than the others and you might be wondering why is that well the main reason is that it doesn't have abstraction or function call Overhead like the four of loop uses the iterator protocol to achieve that syntactic sugar and array for each and reduce require a function call after each iteration that a traditional for Loop doesn't have but the input data matters like if we bump up the number of elements in the array to a million you can see that the benefits of the traditional for Loop increase significantly and now we're getting a 5x performance boost or more but here's the weird part if we reduce the array's length down to about 100 the performance becomes almost even and actually array reduce beats the traditional for Loop so I think the main takeway way here is that the type of loop you use doesn't really matter unless you're looping over massive
Watch from 3:02arrays in which case you'll want to use a traditional for Loop pretty interesting but now I want to show you an optimization that can have a massive impact on performance when searching for a value in an array so in this function I'm generating some testing data that creates a massive array containing product IDs user IDs and emails but then I created another array with 1,000 values which contain some matching values that we want to see if we can find in the big array in vanilla JavaScript the typical way to do this is to use array includes which is a function that will Loop over the array until it finds a matching value and then return a Boolean of true or false in Big O that would give us o of n performance but there's an alternative and more clever way to solve this problem we can take the original array and create a set data structure a set will index everything by unique value and has a method called has that will tell us if that value exists in the set pretty simple but now let's run our Benchmark this time the performance difference is staggering array includes was only able to solve the problem 4.9 times per second while set lookup was able to do the same thing 4.5 million times per second or in other words a million times faster the reason it's so dramatic is because set has o of one performance the unique values are already indexed so it doesn't need to Loop over the entire array it's the same basic concept as creating an index in a relational database now if you're only using array includes on a small number of elements it's probably not worth it to create a set because there is some overhead in creating that index but if you have a large data set it's definitely worth it but now let's talk about sorting arrays there are many ways to do this and I
Watch from 4:33even have a video that compares 10 different sorting algorithms visually but JavaScript also has a built-in array sort method and I was curious to see if I could beat it by implementing three different sorting algorithms like bubble sort quick sort and merge sort I'm not going to go over the implementation in detail but bubble sort is generally considered the simplest algorithm but not very performant while quicksort is a divide and conquer algorithm that is generally considered to be the fastest sorting algorithm for most use cases and then merge sort which is also a divide and conquer algorithm that can perform really well on certain data structures in this Benchmark I'm going to sort an array of 10,000 elements we'll use the JavaScript sort function as our Baseline and when we run this Benchmark we get some pretty interesting results bubble sort obviously sucks big time merge sort has pretty similar performance but quick sort is almost three times faster that's pretty impressive but why is that well part of it has to do with the overhead of function calls and sort but it also really depends on the thing that you're actually sorting like in this case quicksort is able to do a really good job with numbers but let's see what happens if we change the actual test data to an array of strings when we run the same Benchmark but with strings quick sort is still faster but only just a little bit the bottom line is that in JavaScript sort is probably fast enough for most use cases and the fourth rule of programming is that fancy algorithms are buggier than simple ones and they're much harder to Implement use Simple algorithms as well as simple data structures but if you're really looking to optimize a sorting algorithm you
Watch from 6:04probably shouldn't be messing around with JavaScript and instead use a systems language like C or rust Doo itself is actually written in Rust while the bun JavaScript runtime is written in Zig and nodejs and C++ pretty interesting but I think the main thing I learned through all this benchmarking is that virtually all the built-in stuff is good enough benchmarking is fun but it's far more important to get your code working first and that brings us back to the first rule of programming you can't tell where a program is going to spend its time bottlenecks occur in surprising places so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is and the way you prove that is by measuring with tools like Dino bench make sure to check out the full Dino course when it comes out next week and here's a discount code for making it to the end of this video thanks for watching and I will see you in the next one
Watch from 7:35Full transcript
- 0:00
what you're looking at here are the five rules of programming written by the legendary programmer Rob Pike who programmed the go programming language the first rule of programming is do not talk about programming the second rule of programming is to measure don't tune for Speed until you've measured and even then don't unless one part of the code overwhelms the rest this Echoes another legendary programmer Donald canth who
- 0:21
offered similar advice when he said premature optimization is the root of all evil even my dad would tell me measure twice cut once in programming there's a nearly Unlimited a number of ways to skin a cat but the way you write your code matters like as we'll see in JavaScript there's at least four different ways to Loop over an array and count its values but the performance of each technique varies dramatically in
- 0:41
today's video I'll show you how to easily Benchmark your JavaScript code so you can scientifically measure its performance and avoid wasting time optimizing red herrings to help us make benchmarking extremely easy we're going to use the JavaScript runtime Dino which has a built-in benchmarking tool after playing around with it for a few days I was able to achieve some amazing things like I figured out how to make array
- 1:02
includes 100,000 times faster I was able to write a sorting algorithm that outperforms the built-in array sort method in JavaScript and I figured out the fastest way to write a loop let's take a look at how Doo bench works at first you'll want to make sure you have Doo 2 installed and I also want to point out that this video is part of my full Dino course which is now officially in production and should be out around November 7th which will include about 25
- 1:24
videos and multiple projects the other thing I want to point out is that we're measuring JavaScript and its performance only on the doo runtime which under the hood is powered by the V8 engine which also Powers all chromium browsers and no. JS however if you're looking to compare performance between different run times like node Dino and Bun I'd highly recommend this video from Anton Putra which puts all three of them to
- 1:44
the test in a large scale Cloud environment but now let's jump into the code and answer the question what is the fastest way to Loop over an array in JavaScript well I know of at least four different ways to do it which I've represented in these four functions where the goal is to Loop over an array and then sum up the numbers in that array first up we've got the array for each method if you have an array one
- 2:04
option is to use for each provide it with a callback function that mutates a variable that works but there is a cleaner way to do this with array reduce which also takes a callback function but also has an accumulated value is so there's no need to mutate that variable you'll see functional declarative code like this a lot in front-end projects like reactjs however the next option is
- 2:25
to increment the sum using a regular four Loop in JavaScript you can create a four of Loop that will automatically iterate to the end of the array that's nice and readable but the traditional way to write a for Loop is to use this more explicit syntax where we have a variable of I that's incremented as we Loop over the array's length and that gives us four ways to solve the same problem but the big question is which
- 2:45
one will perform the best well the first thing we'll do is create some testing data like in this case generate a large array with 100,000 elements in it and now finally this is where Doo bench comes in on the global Dino namespace you can call the bench method and then either provide it with a regular function to Benchmark or provide it with an object so you can give each Benchmark a name and then the FN property will
- 3:07
take a function which is the actual code that you want to run and measure in this file we'll use doench to set up a benchmark for each one of our functions it also helps to set up a baseline which would typically be your original code and in this case I'm going to set that as our traditional for Loop in Doo these benchmarks don't actually affect your runtime code but they act more like testing code and the way to execute the
- 3:28
benchmarks is to open up the terminal and run the doench command followed by the file name it'll take a few seconds to run but it gives us this report that shows how many iterations of the function it was able to run per second and its average execution time as well as the best case and worst case performance but at a high level the most useful thing is just the summary that shows us which function is fastest and
- 3:49
surprisingly the traditional for Loop is significantly faster than the others and you might be wondering why is that well the main reason is that it doesn't have abstraction or function call Overhead like the four of loop uses the iterator protocol to achieve that syntactic sugar and array for each and reduce require a function call after each iteration that a traditional for Loop doesn't have but
- 4:09
the input data matters like if we bump up the number of elements in the array to a million you can see that the benefits of the traditional for Loop increase significantly and now we're getting a 5x performance boost or more but here's the weird part if we reduce the array's length down to about 100 the performance becomes almost even and actually array reduce beats the traditional for Loop so I think the main takeway way here is that the type of
- 4:30
loop you use doesn't really matter unless you're looping over massive arrays in which case you'll want to use a traditional for Loop pretty interesting but now I want to show you an optimization that can have a massive impact on performance when searching for a value in an array so in this function I'm generating some testing data that creates a massive array containing product IDs user IDs and emails but then
- 4:51
I created another array with 1,000 values which contain some matching values that we want to see if we can find in the big array in vanilla JavaScript the typical way to do this is to use array includes which is a function that will Loop over the array until it finds a matching value and then return a Boolean of true or false in Big O that would give us o of n performance but there's an alternative and more
- 5:12
clever way to solve this problem we can take the original array and create a set data structure a set will index everything by unique value and has a method called has that will tell us if that value exists in the set pretty simple but now let's run our Benchmark this time the performance difference is staggering array includes was only able to solve the problem 4.9 times per second while set lookup was able to do
- 5:34
the same thing 4.5 million times per second or in other words a million times faster the reason it's so dramatic is because set has o of one performance the unique values are already indexed so it doesn't need to Loop over the entire array it's the same basic concept as creating an index in a relational database now if you're only using array includes on a small number of elements
- 5:54
it's probably not worth it to create a set because there is some overhead in creating that index but if you have a large data set it's definitely worth it but now let's talk about sorting arrays there are many ways to do this and I even have a video that compares 10 different sorting algorithms visually but JavaScript also has a built-in array sort method and I was curious to see if I could beat it by implementing three different sorting algorithms like bubble
- 6:16
sort quick sort and merge sort I'm not going to go over the implementation in detail but bubble sort is generally considered the simplest algorithm but not very performant while quicksort is a divide and conquer algorithm that is generally considered to be the fastest sorting algorithm for most use cases and then merge sort which is also
- 6:37
a divide and conquer algorithm that can perform really well on certain data structures in this Benchmark I'm going to sort an array of 10,000 elements we'll use the JavaScript sort function as our Baseline and when we run this Benchmark we get some pretty interesting results bubble sort obviously sucks big time merge sort has pretty similar performance but quick sort is almost
- 6:58
three times faster that's pretty impressive but why is that well part of it has to do with the overhead of function calls and sort but it also really depends on the thing that you're actually sorting like in this case quicksort is able to do a really good job with numbers but let's see what happens if we change the actual test data to an array of strings when we run the same Benchmark but with strings quick sort is still faster but only just
- 7:19
a little bit the bottom line is that in JavaScript sort is probably fast enough for most use cases and the fourth rule of programming is that fancy algorithms are buggier than simple ones and they're much harder to Implement use Simple algorithms as well as simple data structures but if you're really looking to optimize a sorting algorithm you probably shouldn't be messing around with JavaScript and instead use a systems language like C or rust Doo
- 7:40
itself is actually written in Rust while the bun JavaScript runtime is written in Zig and nodejs and C++ pretty interesting but I think the main thing I learned through all this benchmarking is that virtually all the built-in stuff is good enough benchmarking is fun but it's far more important to get your code working first and that brings us back to the first rule of programming you can't tell where a program is going to spend its time bottlenecks occur in surprising
- 8:02
places so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is and the way you prove that is by measuring with tools like Dino bench make sure to check out the full Dino course when it comes out next week and here's a discount code for making it to the end of this video thanks for watching and I will see you in the next one
Description
Learn how to benchmark your JavaScript code in Deno and find out how the way you write code affects performance. Why is a traditional for loop faster than forEach? And is premature optimization the root of all evil?
Use DENOTIME to take 30% off Fireship PRO https://fireship.io/pro
Node vs Deno vs Bun by @AntonPutra • Deno vs. Node.js vs Bun: Performance Compa...
10 Sorting Algorithms • Sorting Algorithms Explained Visually
More from Beyond Fireship
×6.45:04Subtle, yet Beautiful Scroll Animations
Beyond Fireship2M views
×2.98:33Most overpowered way to build mobile apps?
Beyond Fireship925K views
×2.88:23This UI component library is mind-blowing
Beyond Fireship878K views
×2.76:17Industrial-scale Web Scraping with AI & Proxy Networks
Beyond Fireship854K views
