循环中的异步函数运行速度太慢.我该如何提高表现
Async function in for loop works too slow. How can I improve the performance?
在我正在开发的应用程序中,我用鼠标点击谷歌地图绘制了一个圆圈。鼠标单击设置圆心。这个圆的半径是0.5英里。通过使用brandanee的node-gtfs,我进行异步调用以查找半径0.5英里内的路线。每个圆圈通常有多条路线。然后,我在每个路线上为这个圆圈内的一个方向(仅限南行或北行)的最近公交车站做了标记。问题是;它工作缓慢。我将findClosestStop
函数的时间复杂度从n
更改为log(n)
,希望它能产生显著的影响。它起到了作用,但仍然需要4到10秒才能放置所有标记,这取决于附近路线的数量。这是我使用NodeJS和AngularJS的第一个项目。在这个项目之前,我只熟悉JavaScript的语法。我想知道我能做些什么来使这项工作更快?我是不是犯了一个概念错误?当我等待答案时,我会将(查找最近的停止)功能移到后端,看看它是否会对性能产生影响,尽管我不这么认为,因为会有相同的计算量。
如果你需要更多信息,请告诉我。期待听到对此的一些反馈。提前谢谢。
controller.js
...
var distance = new distance.Distance();
...
function createGTFSCluster(name, lat, lng, walk, bike, map) {
var deferred = $q.defer();
var clusterCenter = new graph.Center(lat, lng, map);
var cluster = new graph.NodeCluster(clusterCenter, walkRadius, bikeRadius);
cluster.setName(name);
getRoutesNearby(cluster.clusterCenter, cluster.bikeRadius)
.then(function(results) {
// Set the cluster's nearby routes
var routes = results[0];
cluster.nearbyRoutes = routes;
angular.forEach(routes, function(route, index){
getStopsByRoute(agency_key,route.route_id, 1).then(function(json){
console.log(index, '->', route.route_id);
var stops = json[0];
var closestStop = distance.getClosestStop(stops, cluster);
cluster.setNodes(closestStop, route);
})
});
// Set the cluster's nodes to the stops found
deferred.resolve(cluster);
});
return deferred.promise;
}
...
// Retrieves the routes near a certain point on the map
//
// Input: cluster - A node cluster on the map we are finding routes for
// Output: A promise whose results are the nearby route IDs
function getRoutesNearby(center, radius) {
var deferred = $q.defer();
// Query the GTFS service for nearby routes and draw them
gtfs.getRoutesByLocation(agency_key, center.lat, center.lon, radius)
.then(function(json) {
//Get all route objects not only IDs
var routes = [];
for(index in json){
routes.push(json[index]);
}
// We got the routes, resolve
deferred.resolve(routes);
});
return deferred.promise;
}
...
function getStopsByRoute(agency_key, route_id, direction_id){
var deferred = $q.defer();
gtfs.getStopsByRoute(agency_key, route_id, direction_id)
.then(function(json){ //all stops on the route in one direction
var stopsArr =[];
stopsArr.push(json.data[0].stops);
deferred.resolve(stopsArr);
});
return deferred.promise;
}
距离.js
Distance.prototype.getClosestStop = function (stops, cluster){
var closestStop = findClosestStop(stops, cluster);
return closestStop;
}
function findDistance(stopObj, clusterObj){
var stopCenter = {
lat:stopObj.stop_lat,
lon:stopObj.stop_lon
};
var clusterCenter = clusterObj.clusterCenter;
var lat1 = stopCenter.lat;
var lat2 = clusterCenter.lat;
var lon1 = stopCenter.lon;
var lon2 = clusterCenter.lon;
var x1 = lat2 - lat1;
var x2 = lon2 - lon1;
var dLat = toRadians(x1);
var dLon = toRadians(x2);
var R = 3958.756; // miles
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
}
function toRadians(number){
var inRadian = number * Math.PI / 180;
// console.log('number->', number, 'inRadian->', inRadian);
return inRadian;
}
function findClosestStop(stops, cluster){
//set new indeces
var startIndex = 0;
var endIndex = stops.length-1;
//set new stop objects
var firstStop = stops[startIndex];
var lastStop = stops[endIndex];
var closestStop;
var returnIndex = 0;
//dS: distance between the first stop and the cluster Center
//dE: distance between the last stop and the cluster center
var dS = findDistance(firstStop, cluster);
var dE = findDistance(lastStop, cluster);
if (dS > dE){
startIndex = startIndex+endIndex / 2;
returnIndex = 1;
}
if(dE > dS){
endIndex = startIndex+endIndex / 2;
returnIndex = 0;
}
if(stops.length > 2){
stops = stops.slice(startIndex,(endIndex+1));
return findClosestStop(stops, cluster);
}else if(stops.length === 2){
return stops[returnIndex];
}else{
return stops[0];
}
}
你在哪里浪费时间?
我建议使用一些
console.time(timerName);
太明白你在哪里浪费时间了。如果你确切地知道你在哪里丢了,分析就会容易得多。
105组数据对于客户端应用程序来说应该是没有问题的。
目前,我建议在您的控制台中运行这两个片段
这个片段统计了你的角度挖掘。只需将其放入控制台,然后使用您的应用程序。
(function monitorDigestCycle(angular) {
var injector = angular.element(document.body).injector();
if (!injector) {
throw new Error('Missing Angular injector on the document body');
}
var $rootScope = injector.get('$rootScope');
function dummy() {
console.count('digest cycle');
}
window.stopWatching = $rootScope.$watch(dummy);
console.log('run window.stopWatching() to stop watching the digest cycle');
}(window.angular));
或者这个片段。它包装了一个函数(您需要调整代码段以供自己使用),并记录了函数调用的chrome探查器。这使得分析变得容易。
(function profileScopeMethod() {
var selector = 'find';
var methodName = 'find';
var name = selector + ':' + methodName;
/* global angular */
var el = angular.element(document.getElementById(selector));
var scope = el.scope() || el.isolateScope();
console.assert(scope, 'cannot find scope from ' + name);
var fn = scope[methodName];
console.assert(typeof fn === 'function', 'missing ' + methodName);
var $timeout = el.injector().get('$timeout');
var $q = el.injector().get('$q');
scope[methodName] = function () {
console.profile(name);
console.time(name);
// method can return a value or a promise
var returned = fn();
$q.when(returned).finally(function finishedMethod() {
console.timeStamp('finished', methodName);
$timeout(function afterDOMUpdate() {
console.timeStamp('dom updated after', methodName);
console.timeEnd(name);
console.profileEnd();
scope[methodName] = fn;
console.log('restored', name);
}, 0);
});
};
console.log('wrapped', name, 'for measurements');
}());
在这里,你可以找到更多的代码片段来分析角度应用
https://github.com/bahmutov/code-snippets
相关文章:
- 提高JQuery的性能
- esri javascript异步打印
- JavaScript异步问题
- $translateProvider.useStaticFilesLoader的Angular Translate异步定
- 异步facebook功能
- 异步并行错误
- 在Three.js中导出网格会提高性能吗
- 在Redux中,我应该在哪里编写复杂的异步流
- 角度异步http自动完成
- 如何从SeleniumWebdriver获取异步Javascript响应
- JavaScript数组优化以提高性能
- 如何使用异步调用更改工厂的变量
- 在等待异步任务时永久循环
- 如何在异步函数中使用javascript对象
- 调用后不异步Ajax忽略函数
- learnyounode#9杂耍异步
- 异步获取数据使用JavaScript同步获取数据
- Nodejs服务器-通过使循环迭代异步来提高性能
- 循环中的异步函数运行速度太慢.我该如何提高表现
- 构造NodeJS异步代码以提高内存效率