Code, JavaScript

Benchmarking common JavaScript tasks

There are often different ways of doing the same thing in JavaScript. You shouldn’t waste your time worrying about premature optimizations but there are plenty of times performance does matter. When you are dealing with with huge datasets and lots of DOM elements you can push the browser to it’s limits.

There are several questions I’ve had and I decided to explore them.

Its important to note that these benchmarks are not scientific. They were put together out of curiosity and there are many circumstances that could affect these results. I’m going to talk about what I’ve seen. You should run your own tests and draw your own conclusions.

The results I discuss below took place on Chrome’s V8 JavaScript engine.

Lets look at some common ways of doing things and see how the browser reacts.

Concat vs. Spread

When you want to combine arrays you have a few choices. You can use the old style of arr.concat(arr2) or you can use the spread operator [...arr, ...arr2]. Both of them return a new array.

You might be surprised to find out that for large arrays spread can be about 50% slower for an two arrays with 10,000 items each. I found that concat was consistently faster unless the array was less than 10 items.

Bind vs. Arrow Function

When you pass a callback there are many times you want to preserve your reference to this. You have two choices for how to do this. You can do this.myFunction.bind(this) or () => this.myFunction(). It turns out that using an arrow function is about 83% slower than bind().

That is, unless if you are calling the function multiple times. It is more expensive to set up the function with bind() than it is with an arrow function. So if you are only calling the function once bind is about 90% slower.

Filtering for True

It is a common task to get the truthy values out of an array. There are a few ways to do this. The common ones involve passing something to filter. For some reason filter requires a value.

So should you cast it to a boolean?

arr.filter(Boolean)

Just return the value:

arr.filter((i)=> i);

Or cast it to a boolean using a double negative?

arr.filter((i)=> !!i);

Its a minor difference but using arr.filter(Boolean) is about 9% slower and the no-op arrow function is the fastest. The double negation is about 2% slower and in effect does nothing.

Sets vs Arrays

Sets and Arrays can be used for a lot of the same things. The main difference is that sets are unique and arrays aren’t. The other big differnce is that it is way faster to check if an object exists in a set rather than an array. The difference is off the charts. With 10,000 items JSPref reports Array.includes is 100% slower than Set.has.

But what if you have an Array and you want to check if things exist in it. Should you convert it to a set? Well it turns out creating a set is somewhat expensive. If you needed to check if an Array contained something 200 times you would still be better off keeping it as an Array and using Array.includes rather than converting it to a set and using Set.has. There is an inflection point though. It seems to be right around 400 checks on an array of 10,000 items.

I hope you enjoyed these benchmarks. As always, you should benchmark your usecase and unless your code needs to be highly optimized the most important thing most of the time is how the code looks.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s