Selva Balaji
Selva Balaji

Reputation: 3

Performance issue due to more for loop

Because of the more "for" loops causing performance issue. It's taking 15-20secs to load the page. The first three for loops are getting from three different JSON files.

Code:

$scope.loading = function(item, scode) {
    item.calling = [];
    for (var i = 0; i < $scope.planMapping.length; i++) {
      for (var x = 0; x < $scope.callplanList.length; x++) {
        for (var z = 0; z < $scope.AHOfferScode.length; z++) {
          if (($scope.planMapping[i].PlanScode == $scope.callplanList[x].un_s_code) &&
              ($scope.callplanList[x].offer_type == "REC") &&
              ($scope.callplanList[x].s_code == $scope.AHOfferScode[z])
          ) {
            //console.log($scope.devicesList);
            for (var a = 0; a < $scope.callplanList[x].upfront_cost.length; a++) {
              item.calling.push($scope.callplanList[x]);
            }
          }
        }
      }
    }

Is there any replacement for "for" loop (filter or something) to improve the performance, something like:

euPlanDeviceScodes. PlanScode = CallPlan.un_s_code
availableHandsetOfferScodes = CallPlan.s_code
CallPlan.offer_type = “REC”

Upvotes: 0

Views: 356

Answers (2)

Ramesh Rajendran
Ramesh Rajendran

Reputation: 38663

Use find() instead of using loop to check the if condition. It may restrict a loop

like,

var array1= [1,2,3];
var array2= [3,4,5];
for(var i=0; i < array2.length;i++)
{
var matchedData = array1.find(function(x){ return x===array2[i]});
if(matchedData)
{
console.log(matchedData);
}
}

Now you can reduce one loop. as same logic do it.

Upvotes: 0

Rajesh
Rajesh

Reputation: 24915

As commented before, array functions like filter are useful to improve readability but comes at a cost of performance. The difference is not much but still if you want performant code, for is the best option.

That said, you can improve the logic.

In your loop, you have a condition,

$scope.callplanList[x].offer_type == "REC"

This condition is not dependent on any looping variable and can be processed before looping

$scope.loading = function(item, scode) {
    item.calling = [];

    var recOfferList = $scope.callplanList.filter((plan) => plan.offer_type === 'REC');

    for (var i = 0; i < $scope.planMapping.length; i++) {
      for (var x = 0; x < recOfferList.length; x++) {
        for (var z = 0; z < $scope.AHOfferScode.length; z++) {
          if (($scope.planMapping[i].PlanScode == recOfferList[x].un_s_code) &&
              (recOfferList.s_code == $scope.AHOfferScode[z])
          ) {
            //console.log($scope.devicesList);
            for (var a = 0; a < recOfferList[x].upfront_cost.length; a++) {
              item.calling.push(recOfferList[x]);
            }
          }
        }
      }
    }

Another place for optimization can be the innermost loop:

for (var a = 0; a < $scope.callplanList[x].upfront_cost.length; a++) {
  item.calling.push($scope.callplanList[x]);
}

Above code is not using a anywhere in body. This can be replaced with

item.calling = item.calling.concat(
  new Array.fill($scope.callplanList[x].upfront_cost.length)
  .fill($scope.callplanList[x])
)

Or if you can use ES6 features, may be Array.from

item.calling = item.calling.concat(
  Array.from({
    length: $scope.callplanList[x].upfront_cost.length
  }, () => $scope.callplanList[x])
)

Upvotes: 1

Related Questions