javascript - Nodejs 数百个坐标之间的距离计算阻塞了我的服务器

标签 javascript node.js asynchronous geolocation

我有数百个坐标(纬度,经度)的列表。 对于每个客户请求,我需要计算每对这些点之间的距离。 对于 1,000 个坐标的列表 - 我需要 500 毫秒才能完成,因此它阻塞了我的 Nodejs 服务器。 我如何通过使其异步来“修复”这个问题?我不希望它阻止我的服务器,以便它可以继续处理其他请求..

是否建议打开另一个nodejs进程并将其设为“距离计算服务”或类似的东西?

这是一个示例测试代码:

var pts=[];
for (i=0;i<1000;i++){
    pts.push(randomLatLon());
}
var a;
var b;
var i,j;
var start = new Date();
for (i=0;i<pts.length;i++){
    for (j=0;j<pts.length;j++){
        if (i===j) {
            continue;
        }
        a = pts[i];
        b = pts[j];
        var dist = utils.getDistance(a.lat,a.lon,b.lat,b.lon);
    }
}
console.log('total time',new Date()-start,'ms'); // ~500 ms

这是 utils.getDistance 函数:

E.getDistance = function(lat1,lon1,lat2,lon2) {
  var R = 6371*1000; // Radius of the earth in m
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(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; // Distance in m
  return d;
}

最佳答案

这在一定程度上取决于您需要如何处理结果。您需要一系列距离作为输出吗?

一种方法是使用诸如 Q 之类的 Promise 将每个计算变成一个单独的操作,然后使用 Q.all等待所有计算完成,但是对于 1000x1000 来说这样做可能不是一个好主意,因为您必须在内存中保留一百万个 promise 的数组。根据您需要对输出执行的操作以及原始点数组有多大,按顺序调用每个计算可能会更好,也可能不会更好。一种方法是使用递归:

function calculateDistances(pts) {
    var start = new Date();
    calculateNextDistance(pts, 0, 1).then(function() {
        console.log('total time',new Date()-start,'ms');
    });

    function calculateNextDistance(pts, i, j) {
        return Q().then(function () {
            var a = pts[i];
            var b = pts[j];
            var dist = utils.getDistance(a.lat, a.lon, b.lat, b.lon);

            j++;

            if (j == pts.length) {
                i++;
                j = i + 1;
            }

            if (j < pts.length) {
                return calculateNextDistance(pts, i, j);
            }
        });
    }
}

这对我来说似乎很有效,但请注意,由于所有上下文切换,现在完成计算当然可能需要比 500 毫秒更长的时间。一种折衷方案可能是在每次迭代中进行一些计算。

(顺便说一句,您可以通过不计算 x->y 和 y->x 来消除相当多的计算,这意味着循环可以进入 for (j=i+1;j<pts.length;j++) ,我也在上面的代码中使用了它)

我不知道是否最好生成一个子进程,但这可能值得尝试。

关于javascript - Nodejs 数百个坐标之间的距离计算阻塞了我的服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32113454/

相关文章:

javascript - 卡在新铁路围栏密码中的解密(之字形模式)

javascript - 仅使用客户端代码(无 php)检索推文和帖子

csv - 在 F# 中使用 FileHelperAsyncEngine

javascript - 如何使用 Angular app.js 文件运行 NodeJS API?

javascript - 从使用 Promise 的函数返回 bool 值?

javascript - NodeJS 中未提供回调模式

javascript - 如何在 javascript 中检查 li 元素是否具有内部 ul?

javascript - Adobe AIR 无限制访问...我如何限制它?

html - 如何在index.html 中指定构建编译指示?

node.js - 在 debian 上 npm install homebridge 期间 npm 失败(gyp 错误和安装脚本错误)