Comparing the efficiency of using arrays versus mapping to an object and accessing data in JavaScript

When considering the basics of computer science, it is understood that searching an unsorted list typically occurs in O(n) time, while direct access to an element in an array happens in O(1) time for HashMaps.

So, which approach yields better performance: mapping an array to a dictionary and accessing elements directly, or simply using includes()? This question pertains specifically to JavaScript, as the answer likely hinges on how includes() and {} are implemented at their core.

let y = [1,2,3,4,5]
y.includes(3)

or...

let y = {
          1: true,
          2: true
          3: true
          4: true
          5: true
        }
5 in y

Answer №1

It is indeed true that object lookup operates in constant time - O(1) - making the use of object properties instead of an array a viable option. However, when you simply need to determine if a value exists within a collection, employing a Set would be more suitable. A Set is a generally unordered group of values that can also be searched in linear time. Opting for a plain object would necessitate having values alongside keys, which may not be relevant. Therefore, opting for a Set is recommended.

const set = new Set(['foo', 'bar']);
console.log(set.has('foo'));
console.log(set.has('baz'));

This approach proves beneficial when multiple values need to be checked within the same Set. Nevertheless, adding elements to the Set (similar to adding properties to an object) entails an operation of O(N). Hence, if you only require a single value lookup once, there is no advantage to utilizing either this method or the object technique. In such scenarios, resorting to using an array and the includes method would suffice.

Answer №2

Updated 04/29/2020

The recent analysis pointed out that V8 may be optimizing the array includes calls. In order to achieve more expected results, it is suggested to assign to a variable and use it. The updated version shows Object address as the fastest, followed by Set has, with Array includes trailing in performance (based on my system/browser).

While I still maintain my original point about testing assumptions when making micro-optimizations, it is important to ensure the validity of your tests ;)

Original

Despite the common expectation that Object address and Set has would have better performance than Array includes, benchmarks against Chrome show otherwise.

In my tests with Chrome, Array includes significantly outperformed the other methods.

Local testing with Node yielded more anticipated results where Object address performed the best, Set has came close behind, and Array includes was slightly slower than both.

The key takeaway here is that if you are considering micro-optimizations, it is advisable to benchmark instead of assuming what might work best for your specific scenario. Ultimately, implementation plays a crucial role, as indicated by your question. Therefore, optimizing for the target platform is essential.

Here are the results obtained:

Node (12.6.0):

ops for Object address 7804199
ops for Array includes 5200197
ops for Set has 7178483

Chrome (75.0):

Answer №3

Although not a direct answer to the query, I conducted a related performance test using my Chrome dev tools.

function getRandomInt(max) {
    return Math.floor(Math.random() * max);
}
var arr = [1,2,3];
var t = performance.now();
for (var i = 0; i < 100000; i++) {
    var x = arr.includes(getRandomInt(3));
}
console.log(performance.now() - t);
var t = performance.now();
for (var i = 0; i < 100000; i++) {
    var n = getRandomInt(3);
    var x = n == 1 || n == 2 || n == 3;
}
console.log(performance.now() - t);
VM44:9 9.100000001490116
VM44:16 5.699999995529652

The array includes syntax appealed to me aesthetically, prompting me to assess its impact on performance when used to check if a variable matches one of several enums. Surprisingly, with a short list, like [1,2,3], there seems to be minimal impact on performance. To verify this, I ran another test.

function getRandomInt(max) {
    return Math.floor(Math.random() * max);
}
var t = performance.now();
for (var i = 0; i < 100000; i++) {
    var x = [1,2,3].includes(getRandomInt(3));
}
console.log(performance.now() - t);

var t = performance.now();
for (var i = 0; i < 100000; i++) {
    var n = getRandomInt(3);
    var x = n == 1 || n == 2 || n == 3;
}
console.log(performance.now() - t);
VM83:8 12.600000001490116
VM83:15 4.399999998509884

Interestingly, I found that the method I preferred and actually utilized had a significant impact on performance compared to the initial test, especially when executed multiple times. Therefore, incorporating it within an Array.filter in scenarios like a React Redux selector might not be advisable as initially intended.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Wrap the words around to fit a rectangle with a specific ratio, rather than a specific size

Does anyone have a solution for breaking text at word boundaries to perfectly fit a rectangle with a specific approximate ratio, such as 60:40 (width:height)? Please note that this is not just about setting a width limit (e.g. 80 characters or 600px) and ...

Locate the next element with the same class using jQuery across the entire document

I'm working with the following HTML: <section class="slide current"></section> <section> <div class="slide"></div> <div class="slide"></div> </section> <section class="slide"></section> ...

Error 500 on Firebase: Issue solving "firebase" in "firebase.js" not resolved

Struggling to incorporate Firebase into my latest React project, I keep encountering the dreaded "The development server returned response error code: 500." Despite creating a firebase.js file to house my Firebase configuration details, I am at a loss as ...

The PHP echo function is unable to properly display the values when comparing two arrays

I am trying to extract and compare values from two arrays using PHP. Below is the code that I have written: $maindata=array(array('id'=>3),array('id'=>7),array('id'=>9)); $childata=array(array('id'=>3), ...

Angular variable resets to initial value after modification

Currently, I am utilizing ui-router to handle the state management for the admin segment of a project. The admin area includes the ability to browse through various categories. In this category management module, I am working on implementing a breadcrumb l ...

Changing date and time into milliseconds within AngularJS

Today's date is: var timeFormat = 'dd MMM, yyyy hh:mm:ss a'; var todayDate = dateFormat(new Date(), timeFormat); Can we convert today's date to milliseconds using AngularJS? Alternatively, how can we use the JavaScript function getT ...

Breaking up an array in PHP according to search outcomes

My dataset consists of a multidimensional array generated from a MySQL query that aggregates results by various groups and sums. The array details costtotal and hitcount for different variations of 'ad_type', 'click_status', and 'l ...

Tips on creating a transition in React to showcase fresh HTML content depending on the recent state changes

I am completely new to React and recently completed a project called Random Quote Machine. The main objective was to have a method triggered inside React when the user clicks a button, changing the state value and re-rendering to display a new quote on the ...

AngularJS - retrieving and displaying the selected value from an HTML dropdown menu

Could someone help me figure out why the Land selection is empty when trying to display it as {{ selectCenter.land }}? For reference, here is a functional plunker: http://plnkr.co/edit/Q8jhdJltlh14oBBLeHJ9?p=preview And the relevant code snippet: ...

Saving functions in the localStorage API of HTML5: A step-by-step guide

I have encountered an issue while trying to store an array in local storage using JSON.stringify. The array contains functions (referred to as promises) within an object, but it seems that when I convert the array to a string, the functions are removed. Su ...

Make a POST request using Express API, supporting both JSON and XML data

I am facing a unique challenge with my express API. While it typically accepts JSON post requests, there is one particular API that requires an XML post body instead. To set up my express app accordingly, I have used the following configuration: // Init ...

Calculating variables in JavaScript

Explanation from Mozilla Documentation: console.log((function(...args) {}).length); // The result is 0 because the rest parameter is not counted console.log((function(a, b = 1, c) {}).length); // The result is 1 because only parameters before th ...

Creating Transparent Rounded Backgrounds in Google Chrome Packaged Apps: Achieving the same look as Google Hangout app

Looking at the screenshot below, it is evident that the Hangout app has a fully transparent design with background shadow effect applied to it. I have tried various methods in vain, such as applying CSS styling to the "html" and "body" tags of the page, a ...

Using setAttribute will convert the attribute name to lowercase

When creating elements, I use the following code: var l = document.createElement("label");. I then assign attributes with l.setAttribute("formControlName","e");. However, a problem arises where the setAttribute method converts formControlName to lowercase ...

Ways to clear TextField status

My question is about a Textfield. In the case where the state is null but the text field value is showing in the Textfield. <TextField style={{ width: '65%'}} id="standard-search" ...

Error encountered when accessing Spotify API. The requested action requires proper permissions which are currently missing. Issue arises when attempting to

I am attempting to use the spotify-web-api-node library to play a track on my application const playSong = async () => { // Verify access token with console.log(spotifyApi.getAccessToken()) setCurrentTrackId(track.track.id); setIsPlay ...

JavaScript - Retrieve the name of an object from a separate array

Is it possible to dynamically map rows and columns in a table component using arrays of objects? For example, I have two arrays of objects like this: const columnData = [ { id: 'name', label: 'Name' }, { id: 'value', lab ...

Node scripts and node bins are causing errors in Vue.js when running npm

While attempting to run my Vue project with the command npm run serve I encountered an error message that read: [email protected] serve /home/numan/Desktop/vue-getting-started/07-accessing-data/begin/vue-heroes vue-cli-service serve sh: 1: vue- ...

Setting the default selected row to the first row in ag-Grid (Angular)

Is there a way to automatically select the first row in ag-grid when using it with Angular? If you're curious, here's some code that may help: https://stackblitz.com/edit/ag-grid-angular-hello-world-xabqct?file=src/app/app.component.ts I'm ...

Looking for assistance in setting up a personalized slideshow to automatically play on its

Recently, I have taken responsibility for a project that was initiated by someone else. The website contains a customized slideshow on its homepage. To meet the client's requirements, I have already made some alterations to the appearance and feel of ...