Improving the efficiency of the for loop

Recently, I've noticed that my JavaScript program is taking quite a bit of time to process the for loop snippet below.

    let storage = [];
    for (var i = 0; i<location.length; i++) {
        if (location.lastIndexOf(location[i]) === location.indexOf(location[i])) {
            storage.push([location[i], value[i]]);
        }
        else {
            const comparisonList = value.filter((_,j) => {
                const cond = location[j] === location[i] && j!==i;
                return cond; 
            });
            let avg = comparisonList.reduce((a,b)=>a+b,0) / comparisonList.length;
            let deviation = comparisonList.reduce((a,b)=>a+(b-avg)**2/comparisonList.length,0) ** 0.5;
            Math.abs(avg-value[i]) <= 3 * deviation && storage.push([location[i],value[i]]);
        }
    }

I'm considering implementing a recursive solution as I suspect it might lead to better performance, although I'm unsure of how to go about designing it.

Answer №1

Here, we present two solutions that rely on two helper functions. The sum function calculates the total of an array of numbers, while the groupBy function groups elements based on a specified function into an object with keys representing the result of applying the function to the data and values comprising all elements that match the particular key. For example:

groupBy(x => x % 10)([21, 15, 11, 3, 5, 1, 7])
//=> {"1": [21, 11, 1], "3": [3], "5": [15, 5], "7": [7]}

We utilize this approach to consolidate prices for each area. In both solutions, we first apply this grouping technique to the data and then flatten the resulting object into an array of area/priceList pairs like so:

[[1200, [12000, 14000, 13000]], [1300, [24000, 22000]], [2000, [30000]]]

The initial solution, which is my preferred method, involves including the current item while calculating outliers. This approach seems more intuitive (why should every pair include two outliers?) and proves to be simpler and more efficient. The implementation looks as follows:

// Code snippet provided
.as-console-wrapper {max-height: 100% !important; top: 0}

Alternatively, if we aim to exclude the current item when determining outliers, we can adopt this different strategy:

// Another code snippet provided
.as-console-wrapper {max-height: 100% !important; top: 0}

In this latter solution, I have attempted to optimize the mean calculation by precomputing the total and subtracting the current value. However, this optimization may not yield significant improvements for small datasets, where computing the full mean within the inner loop could be more efficient.

I have not conducted benchmark tests to prove the performance superiority of these solutions over your existing approach. Nonetheless, I believe the first solution, along with Bergi's similar one, would outperform significantly due to their initial grouping step and avoidance of redundant calculations per group.

The second solution might not offer a substantial performance advantage since it requires repetitive computations.


An interesting performance enhancement worth mentioning relates to the difference between:

sum(xs) / xs.length

and

sum(xs.map(x => x / xs.length))

We can minimize division operations by conducting this computation once at the end rather than dividing at each accumulation step.

Answer №2

for (var i = 0; i<area.length; i++) {
  if (area.lastIndexOf(area[i]) === area.indexOf(area[i])) …
  compList = price.filter((_,j) => area[j] === area[i] && j!==i)
  …
}

Using a Map to store prices categorized by area is a more efficient way than the previous method outlined above, especially for larger arrays:

const pricesByArea = new Map();
for (let i=0; i<area.length; i++) {
  let prices = pricesByArea.get(area[i]);
  if (!prices) pricesByArea.set(area[i], prices = []);
  prices.push(price[i]);
}

Subsequently, process the stored data as follows:

const store = [];
for (const [area, prices] of pricesByArea) {
  if (compList.length == 1) {
    store.push([area, compList[0]]);
  } else {
    for (const [i, price] of prices.entries()) {
      const compList = prices.filter((_, j) => i != j);
      const mean = compList.reduce((a,b)=>a+b,0) / compList.length;
      const std = compList.reduce((a,b)=>a+(b-mean)**2/compList.length,0) ** 0.5;
      if (Math.abs(mean-price) <= 3 * std) {
        store.push([area, price]);
      }
    }
  }
}

(The output will remain consistent with the original code, with exception to the order inside store)

To improve accuracy in determining the mean price per area, consider revising the definition slightly:

const store = [];
for (const [area, prices] of pricesByArea) {
  if (prices.length == 1) {
    store.push([area, prices[0]]);
  } else {
    const mean = prices.reduce((a,b)=>a+b,0) / prices.length;
    const std = prices.reduce((a,b)=>a+(b-mean)**2/prices.length,0) ** 0.5;
    for (const price of prices)
      if (Math.abs(mean-price) <= 3 * std)
        store.push([area, price]);
  }
}

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

Avoid running multiple AJAX queries simultaneously

Utilizing ajax, I am able to retrieve content and perform additional ajax requests within that content using .ajaxComplete(). This is the method I have implemented: $( document ).ajaxComplete(function() { $(".deleteParticipant").click(function(){ var ...

The impressive 3D environment rendered by three.js appears crisp and detailed in Chrome, yet lacks clarity in Firefox

When viewing the same three-dimensional scene created using three.js, the clarity differs between Chrome and Firefox: Chrome (clear): Firefox (blurred): ...

Searching for a nested element within an AngularJS directive

While working on a directive, I am facing an issue with using the element parameter to locate its children by class name. .directive("ngScrollList", function(){ return { restrict: 'AE', link: function($scope, element, attrs, ...

By default, populate the text area in an HTML form with content fetched from the database

Can anyone provide suggestions on the best method to extract text from a database field and place it as the default text in a text area? I am thinking of assigning the field to a variable and then utilizing javascript to set it as the default text, but I ...

There seems to be an issue with the JavaScript code failing after the AJAX request fails

When attempting to retrieve data from a local network IP address, everything functions correctly within the local network. However, issues arise when trying to access the data from outside the network. The problem is that the error block in jQuery does not ...

"Encountering an issue with AJAX file upload displaying an error message for

Before I showcase my code, allow me to explain my objective. My goal is to create a page that updates a user's details in the database using AJAX. Initially, I successfully achieved this task. Subsequently, I wanted to enhance the functionality by inc ...

A new Vue component is regenerated after the creation method is called

I am facing an issue with setting the margin of an image to display it in the center of the page when the image dialog is created. I have calculated the margin in the component's created method and everything seems fine during debugging as the image i ...

Processing .obj file and converting it into a string format with the help of three

I have a unique challenge where my program creates .obj files at runtime and stores them as strings. I am now looking to load these generated .obj files using the load() function in three.js (OBJLoader). Currently, the load() function uses an HTTP request ...

Unable to access socket.io after modifying the application's URL

There's been a lot of discussion surrounding this topic, but most of it doesn't apply to my situation since I am using express 4.16.4 and socket.io 2.2.0. Also, my example is already functional on both localhost and remote hosting. When setting ...

The button functionality gets hindered within the Bootstrap well

I'm trying to figure out what's wrong with my code. Here is the code: https://jsfiddle.net/8rhscamn/ <div class="well"> <div class="row text-center"> <div class="col-sm-1">& ...

Switch a Laravel Collection or Array into a JavaScript Array

Is there a way to transfer data from Laravel to a JavaScript array? I have extracted the data from my AppServiceProvider and decoded it using json_decode, as shown below: View::composer('*', function($view) { $users = Users::all(); $view-& ...

Customize the position of nodes and their descendants in a d3 tree chart by setting specific x and y coordinates

I am in need of a d3 tree structure that looks like this. https://i.sstatic.net/X6U3u.png There are two key points to understand from the image above: Headers will have multiple parents(wells). I need to be able to drag and drop links connecting w ...

Is there a more concise method for accepting a collection of interfaces in TypeScript?

Issue I am facing a simplified version of a problem with my model: Here is how my model currently looks: interface Instrument { name: string; // ...more properties shared by all instruments... } interface Guitar extends Instrument { type: &q ...

Using PHP and JavaScript to keep track of file modifications

Being a beginner in PHP and Javascript, I recently created a basic Clock application using Javascript which worked out successfully. Now, I have a file that will automatically change its content. For example, it might look something like this: "12h15: eat ...

How can you change the opacity of a div's background color using jQuery?

I am experimenting with jQuery to create a smooth transition effect for opening and closing a hamburger menu. By adding or removing the classes 'no-colour' and 'colour', I can control the background color of the menu. Currently, the ba ...

The Slack Bot is having trouble downloading files from direct messages, but it is successfully downloading them when uploaded to a channel

I have developed a program to retrieve files using a code snippet provided by a Slack bot. Below is the code: var https = require('https'); var fs = require('fs'); var downloadFile = function (url, dest){ var slug = url.split(&apos ...

Using Javascript to dynamically update custom CSS properties

I am currently utilizing the paper-scroll-header-panel along with a custom CSS property paper-scroll-header-panel { --paper-scroll-header-panel-full-header: { background-image: url(images/abcd.jpg); }; } in order to customize th ...

Determine the variance between two indices within a condensed array (JavaScript)

After extracting data from a CSV file containing crypto transactions, I sorted the results based on the Token column. Here is an overview of the grouped array: **[ ETH:[ [ 1571967200, 'DEPOSIT', 'ETH', 0.68364 ], [ 157196 ...

Transferring a string value from C#.NET to JavaScript

So, imagine having a string variable that is passed to a JavaScript function using the following code. Chart1.Series["Series1"].Points[counter].MapAreaAttributes = "onmouseover=\"showAlert("+tempString+",event);\""; The JavaScript function look ...

What could be causing the error message "time.replaceAll is not a recognized function" to appear on my screen?

I keep encountering an error that says "time.replaceAll is not a function" and I'm unable to identify the reason why. Interestingly, when I tested time.replaceAll in an online code editor, it worked perfectly. exports.ForgotPasswordToken = async (req, ...