2013-10-23 64 views
1

我一直在與一個大小不等的大數據數組進行鬥爭,大概數據長度大概在100〜200之間,但可以更大。AngularJS和Javascript大數據循環性能

數據項本身來自生成對象數組的自定義報告算法。

對象例如:

ts:budget: "foo" 
ts:category: "foo" 
ts:client: "foo" 
ts:entryTime: 14.5 
ts:project: "foo (00000000)" 
ts:task: "foo" 
ts:user: "foo" 
ts:userGroup: "foo" 

乘上100〜200對象的例子,這就是我的工作。沒有什麼大規模的,所以我並不期待這麼大的表現。我非常懷疑這是我的工廠代碼,這是問題所在,但我已經完成並優化了幾個領域(即用native for循環替換angular.ForEach循環),並且回退了性能,但仍佔用了大約25%的CPU使用量當工廠被叫時。

廠代碼:

var report = '{"userID":"111868022517936189634", "jsonPayload":{"metrics":[{"ID":"ts:entryTime"}],"dimensions":[' + dimensions + '],"filters":[]}}'; 
var promise = $http.post("report.php?action=show&type=report&rangeStart=" + rangeStart + "&rangeEnd=" + rangeEnd, report).success(function(results) { 
    var uniqueArray = []; 
    for (m = array.length - 1; m >= 0; m--) { 
     var subItemUniqueArray = []; 
     if (uniqueArray.indexOf(array[m]) == -1) { 
      uniqueArray.push(array[m]); 
      for (k = uniqueRequireArray.length - 1; k >= 0; k--) { 
       uniqueRequireArray[k] == 'category' ? array[m]['categories'] = [] : array[m][uniqueRequireArray[k] + 's'] = []; 
      } 
      for (j = results.length - 1; j >= 0; j--) { 
       for (var x in results[j]) { 
        if (results[j].hasOwnProperty(x)) { 
         if (x == 'ts:' + type) { 
          var relationString = null; 
          type != 'project' ? relationString = array[m][relation] : relationString = array[m].name + ' (' + array[m].projectNumber +')'; 
          if (results[j][x] == relationString) { 
           for (i = uniqueRequireArray.length - 1; i >= 0; i--) { 
            var obj = { 
             'item': results[j]['ts:' + uniqueRequireArray[i] + ''] 
            } 
            if (subItemUniqueArray.indexOf(obj.item) == -1) { 
             uniqueRequireArray[i] == 'category' ? array[m]['categories'].push(obj) : array[m][uniqueRequireArray[i] + 's'].push(obj); 
             subItemUniqueArray.push(obj.item); 
             obj.entryTime = results[j]['ts:entryTime']; 

             if (uniqueRequireArray[i] == 'user') {obj.externalID = $userlookup.email(obj.item);} // add user externalID 
             if (uniqueRequireArray[i] == 'category') {obj.colour = $colourlookup.name(obj.item);} // add category colour 
             if (angular.isDefined(results[j]['ts:category'])) { 
              if (uniqueRequireArray[i] == 'budget') {obj.colour = $colourlookup.name(results[j]['ts:category']);} // add budget colour 
              if (uniqueRequireArray[i] == 'task') {obj.colour = $colourlookup.name(results[j]['ts:category']);} // add task colour 
             } 
            } 
            else { 
             obj.entryTime += results[j]['ts:entryTime']; 
            } 
           } 
           break; 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
}).error(function(data) { 
     $debug.admin('Service: Failed getting report results for overview', 'error', true); 
}).then(function(results) { 
    return results; 
}); 
return promise; 

我懷疑具有5 for循環是理想的性能,特別是作爲循環的最頂部是通過饋入可以在任何地方從30到服務另一個陣列驅動200個項目的長度。

給出大致一分鐘,該功能成功創建正確的數據綁定並填充前端中繼器和CPU使用率下降。就在那個時候,應用程序完全無法使用。

任何幫助將大力讚賞!

+0

我相信,如果你希望人們調試/優化你的代碼,你至少應該提供一個可用的/可運行的例子。也許建立一個[plunker](http://plnkr.co)。 – Yoshi

回答

2

對於使用類似http://danieltao.com/lazy.js/的東西,或者如果這對您還不適用,那麼至少應該使用http://underscorejs.org/路線,您的情況可能會非常好。

它看起來像你試圖實現可能會更好地解決使用功能路線比你正在採取的迭代方法。爲什麼?

  1. 它最終會變得更具可讀性。
  2. 這些庫是由那裏的專家編寫的。利用他們的專業知識可能是一個好主意。
  3. 您的要求乞求更多功能和鏈接的方法(查看所有循環)。

一旦你這樣做,如果你仍然遇到性能問題 - 那麼我會建議用手寫指令替換整個ng-repeat序列。

你可能想要查看已經在線的東西,這可以幫助你在這個方向。

http://tech.small-improvements.com/2013/09/10/angularjs-performance-with-large-lists/

+0

非常感謝!指出我正確的方向:http://tech.small-improvements.com/2013/09/10/angularjs-performance-with-large-lists/它指向我:https://github.com/Pasvaz/ bindonce - $ apply和$ digest是造成問題的90%的原因。我還恢復了幾個性能增強器,以確保服務更具可讀性。 – tinyBIGideas