Improving the performance of a function that generates all possible combinations of elements within an array

After coming across this function online, I decided to optimize it.

For instance, if we have an input of [1, 2, 3], the corresponding output would be

[[1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

Below is the code snippet:

const combinations = arr => {
  let parentValue = [];
  let cursor = 0;

  for (const parentThis of arr) {
    const value = [[parentThis]];
    for (const thiss of parentValue) {
      value.push(thiss.concat([parentThis]));
    }
    parentValue = parentValue.concat(value);
  }
  return parentValue;
};

(I apologize for the unconventional variable names; it's due to executing this as a MongoDB aggregation)

Executing this operation 10,000 times on an array consisting of 10 elements takes approximately 23 seconds. How can I enhance its performance? I'm willing to make some compromises.

One immediate enhancement I noticed was reducing the number of elements. When executed 10,000 times on an array with 9 elements, the time taken decreased to 9 seconds.

I suspect that rejecting certain outputs before they are created (such as single-element combinations and all-elements combinations which might not be very useful) could lead to further improvements, but I’m struggling to implement this in code.

I attempted to enhance the performance by eliminating the initial iteration (by providing [arr[0]] as the initialValue and commencing the outer loop from the second element), although it didn’t result in a noticeable difference.

Answer №1

It takes approximately 1 second to run through 10,000 iterations on an array containing 10 elements.

function powerset(A){
  const n = A.length;
  const numSets = (1 << n) - 1;
  const result = new Array(numSets);

  for (let k=1; k<=numSets; k++){
    const set = [];
    result[k - 1] = set;
    let temp = k;
    let i = 0;
    while (temp){
      if (temp & 1)
        set.push(A[i]);
      temp >>= 1;
      i += 1;
    }
  }
  
  return result;
}


var A = [1,2,3,4,5,6,7,8,9,10];
var start = new Date;
for (let i=0; i<10000; i++)
  var t = powerset(A);
console.log((new Date - start) / 1000);

georg suggested in the comments under this answer that replacing

const result = new Array(numSets);
with const result = []; and changing the assignment to result.push(set); could potentially improve efficiency further. This was tested on node with array sizes ranging from 15-20.

Answer №2

A slight nudge might be all that's needed to optimize the code.

// Instead of using concat method, try using the spread operator for better performance.
parentValue.push(...value);

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

Encountering an issue when running npm build on server

I attempted to deploy my application on the hosting server and encountered the following error: Failed to compile. ./node_modules/next/dist/pages/_app.js Error: failed to process The global thread pool has not been initialized.: ThreadPoolBuildError { kin ...

Is it considered poor practice to create refs outside of a component?

Currently, I am developing a library that requires exporting certain functions for users to utilize. These functions rely on having access to a component reference in order to manipulate classNames and enable auto-scroll functionalities, among other things ...

When the function is clicked, an error occurs that says: "return is a reserved word"

I am attempting to trigger a popup window when clicking on the link button, but I keep getting an error stating that "return" is a keyword and expecting an identifier. I'm using ASP.NET for this functionality. <asp:LinkButton ID="CommentAction" h ...

Ways to transfer a function as attributes from one functional element to another?

I've encountered an issue when passing a function as a prop from one functional component (Dashboard) to another (Event). Every time I click the button on the child component that holds the passed function prop in the onClick value, it results in an e ...

Need Root Directories in Browserify and Using NPM (eliminating the constant use of '../../../..' in both cases)

Despite my extensive search for a solution to this issue, I have been unsuccessful so far – even after referring to the amazing gist on improving local require paths and thoroughly reading the Browserify handbook section on Avoiding ../../../../... I am ...

Tips for Managing the Hardware Back Button in Ionic 3

Can someone help me enable the hardware back button in Ionic 3? I want it to redirect to specific pages and display designated content. Being new to Ionic 3, I need guidance on how to set up the hardware device buttons for redirection. ...

Struggling to find your way around the header on my website? Let me give

I'm looking to display certain links prominently at the top of a page, similar to this example: "home > page1 > link1 > article 1." Can someone advise on how to achieve this using HTML, PHP, or jQuery? ...

Even though I have successfully compiled on Heroku, I am still encountering the dreaded Application Error

Looking for help with a simple express/node application to test Heroku? Check out my app.js: const express = require('express') const app = express() const port = '8080' || process.env.PORT; app.get('/', function (req, res) ...

JavaScript Language Conversion Templating

I'm currently revamping the frontend for Facebook's internationalization XFBML tag, which has been nonfunctional for a while. I'm almost done with the updates but I have hit a roadblock: swapping out tokenized translations without losing dat ...

Invoke a React component within a conditional statement

There is a function for exporting data in either csv or xls format based on an argument specifying the type. The functionality works flawlessly for xls but encounters issues with csv. Here's the code snippet: const exportFile = (exportType) => { ...

The Forward and Back Buttons respond based on the current position of the caret

Exploring the concept of a Keypad-Login. I am trying to create Back and Forward buttons. However, the back and forward buttons are currently inserting the letters at the end of the input value instead of at the caret position. The input field is disabled, ...

Implementing CSRF token for the current window's location

Is there a way to add a CSRF token to all instances where window.location.href is used in my Javascript code? It's not possible to override the window.location object and its properties like window.location.href. Creating a universal function to inc ...

Encountering a tIDENTIFIER syntax error while trying to include a button_tag in Rails

Currently, I am in the process of developing a rails application and my aim is to incorporate a button that executes a javascript onclick function. The code snippet I am using for this purpose is: <%= button_tag "Action" type: "button", onclick: "test( ...

Deactivate CS:GO Dedicated Server using Node.js child_process

I've been attempting to manage multiple Counter Strike: Global Offensive dedicated servers programmatically. The process is running smoothly, however, I am facing a challenge in shutting it down completely. Upon starting the server, two processes are ...

Incorporate a new substance into a THREEJS Mesh

Is there a way to add a material to an existing mesh without calling the mesh constructor again? I already have a mesh created using the constructor: var mesh = new THREE.Mesh(geometry, material); Now I have created another material in my code: ...

Transfer information via query or retrieve from storage in Vue

When considering sending a data variable to another component, is it more efficient to send it via query using a router or save the data in-store? Which method would be more optimal? router.replace({ name: 'routerName', query: { param ...

Tips for showcasing several images with accompanying content once the webpage has finished loading

I am faced with an issue on my PHP website. The website is a social networking platform with numerous images and contents. I am seeking a way to first display only the content to the user, then show the images after they have all finished loading. Addition ...

The Express/Mongoose route consistently modifies the identical item

I'm encountering an issue where any attempt to update or create a new item results in only creating one item and then updating that same item regardless of the input. Is there something incorrect with this route? // @route POST api/item // @desc ...

Using JavaScript and node.js, make sure to wait for the response from socket.on before proceeding

My task involves retrieving information from the server on the client side. When a client first connects to the server, this is what happens: socket.on('adduser', function(username){ // miscellaneous code to set num_player and other variabl ...

The output of jquery's val() function will not show the actual value

Is it proper to use html() for setting content in non-form elements like divs? This question has come up a few times, which I wasn't aware of. I've been working on setting a value after fetching comments through a $.ajax call. When I check the v ...