The Fastest Way to Find Minimum and Maximum Values in an Array in JavaScript

The Fastest Way to Find Minimum and Maximum Values in an Array in JavaScript

Is the spread operator slower than a for loop in JavaScript?

JavaScript offers several ways to find the smallest and largest numbers in a list, including the built-in Math functions and sorting the array numerically. I compare the performance of 5 methods using jsPerf ? and the spread operator loses.

Image for postPhoto by Leio McLaren (@leiomclaren) on Unsplash

Sometimes, given an array of numbers in JavaScript, the smallest or largest value needs to be identified ? and quickly!

There are several built-in ways to find a minimum or maximum value from an array in JavaScript, including using the Math functions with the spread operator (?) and sorting the array numerically with .sort().

In this article, I explain how each method works, then I compare the performance of 5 different methods of finding the minimum and maximum values of an array of numbers in JavaScript.

Image for postPhoto by Gautier Salles on Unsplash

Using Math functions

The built-in Math functions Math.min() and Math.max() do exactly what one would expect ? they return the smallest or largest number of the list of numbers passed to them as arguments.

Since Math.min() and Math.max() both expect the numbers as arguments, and not an array, they do not seem at first choice to be good options for getting the smallest or largest number from an array:

On first glance, it looks like we need a different approach. Thankfully, using the ES6 feature spread syntax (?) makes arrays easily compatible with these functions, as I explain in the next section.

Image for postPhoto by Quino Al on Unsplash

Math.min(?array) and Math.max(?array)

?[The spread] operator causes the values in the array to be expanded, or ?spread,? into the function?s arguments.? ? Joel Lovera on jstips.co

The spread operator (?) in JavaScript can expand an array of numbers into the list of arguments, such as with Math.min() & Math.max():

Using the three magic dots (?) makes it easy to call any function expecting arguments, like these built-in Math functions, using an array.

Image for postPhoto by Joe Cook on Unsplash

Without the spread operator

If one is programming to support older browsers, like Internet Explorer, and not using a tool like Babel for compiling the JavaScript code into older syntax with a plugin like babel-plugin-transform-spread, then the spread operator is not going to work.

Here is the current browser compatibility chart for the spread operator:

Image for post

Calling the function Function.prototype.apply() will have the same effect as the spread syntax:

Note that the first argument to .apply() is the target for this, which in this case does not matter, so I passed in null as the first argument.

Image for postPhoto by Mathias Elle on Unsplash

Sorting the list numerically

JavaScript defaults to a lexicographical (alphabetical) sort, where numbers are coerced into strings and then sorted alphabetically.

Sorting an array of numbers numerically in JavaScript is accomplished by passing the Array.prototype.sort() function a ?comparison operator.?

For example, the code .sort((a,b) => a-b) will sort numbers in ascending order from smallest to largest.

Once sorted, the first number will be the min and the last the max:

Image for postPhoto by Phil Reid on Unsplash

Using a for loop or .reduce()

Either a for loop or the Array.prototype.reduce() method can be used to find the minimum and maximum numbers in an array:

Brandon Morelli reported previously on Codeburst.io that these methods may be fastest, so I compare the performance of all 5 methods next.

Image for postPhoto by Stphane Juban on Unsplash

Performance testing

I ran some tests using jsPerf, a free tool for testing the performance of JavaScript code in the browser. Each code sample finds the minimum and maximum of a random array of 40 numbers. Here are the results:

Image for post

Wow! For some reason the spread operator is half the speed of the other methods. Since using .apply() works quickly, it appears using the spread operator over 40 arguments really slows things down.

Image for post

It appears to not be the fault of the Math.min() or Math.max() functions themselves per se, since a for loop that avoids those functions has basically the same performance for this test case of 40 random items.

Image for postPhoto by Quentin Rey on Unsplash

A second look: 4000 items

I updated the test suite to generate a 4000 item array to examine if it changes the comparative performance of finding the min and max.

Indeed, it does, with the spread operator being 92% slower:

Image for post

This shows that the performance drop is associated with the spread operator in a way that scales with the number of arguments being spread.

Image for post

With very large arrays, the for loop is fastest by far, with .apply() coming in second, .sort() and .reduce() tied for third, and spread dead last.

It is worth noting that using Babel to compile the code may restore some performance for large and very large arrays, since it will transpile the spread operator to the .apply() syntax using babel-plugin-transform-spread.

Image for postPhoto by Andy Brunner on Unsplash

A third look: Just 3 items

However, don?t throw the spread operator out just quite yet ? there is no performance difference when we drop down to 3 items:

Image for post

So, for day-to-day use, the spread operator works brilliantly.

Image for post

Meanwhile, the iterative for loop is 3% slower than the spread operator when only dealing with an array of only 3 items.

Image for postPhoto by Joshua Earle on Unsplash

Conclusion

There are several ways to find the smallest and largest numbers in a JavaScript array, and the performance of each method varies based on the number of values in the array.

The most convenient way is using the syntax Math.min(…array) and Math.max(…array)? using ES6?s spread operator (?) to spread the array into the arguments expected by JavaScript?s built-in Math functions.

However, when dealing with large arrays of 40 items or more, using the spread operator has significantly worse performance compared to other methods of finding the minimum and maximum.

What to do for larger arrays

For large arrays, using Math.min.apply(null,array) and Math.max.apply(null,array) restores the lost performance from the spread operator and allows one to continue to use the built-in Math functions.

This is actually exactly what Babel does with babel-plugin-transform-spread, so compiling your JavaScript code will help with arrays around 40 items.

Finally, with very large arrays of 4000 items or more, a for loop is the fastest method by far, so keep that in mind. It may be ugly, but it works.

Now go find some minimums and maximums! ?

Image for postPhoto by Hannah Reding on Unsplash

Further reading

  • GeeksforGeeks explores using .map() and .reduce() to find min/max:

Max/Min value of an attribute in an array of objects in JavaScript – GeeksforGeeks

Given an array of objects and the task is to get the maximum and minimum value from the array of objects. There are a?

www.geeksforgeeks.org

  • Dan Vega finds the maximum id in an array of objects on his blog:

How to find the max id in an array of objects in JavaScript

I was recently putting together a tutorial for some students and I came across an issue that I am sure we have all come?

www.danvega.dev

  • The site w3resource has a visual tutorial on finding a minimum:

JavaScript Math: Find the lowest value in an array – w3resource

Write a JavaScript function to find the lowest value in an array. Test Data : console.log(min([12,34,56,1]))?

www.w3resource.com

  • The library d3-array includes the useful .minIndex() & .maxIndex(), although a for loop will likely be faster for very large arrays:

d3/d3-array

Array manipulation, ordering, searching, summarizing, etc. – d3/d3-array

github.com

  • Brandon Morelli found for loops are fast in his article on codeburst.io:

JavaScript: Finding Minimum and Maximum values in an Array of Objects

Three potential solutions. But which is fastest?

codeburst.io

  • Previous research on very large arrays of 250,000 items published on the Microsoft devblog showed that for loops are the fastest method by far:

Find the index of the smallest element in a JavaScript array | The Old New Thing

Today’s Little Program isn’t even a program. It’s just a function. The problem statement is as follows: Given a?

devblogs.microsoft.com

Image for postPhoto by Rachel Cook on Unsplash

15

No Responses

Write a response