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

我有一个数百个坐标(lat,lon)的列表。 对于每个客户端请求,我需要计算每对这些点之间的距离。 对于1000个坐标的列表 – 这需要我500毫秒,所以它阻止我的nodejs服务器。 我怎样才能修复这个asynchronous? 我不希望它阻止我的服务器,所以它可以继续处理其他请求..

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

以下是一个示例testing代码:

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这样的承诺,将每个计算分成一个单独的操作,然后使用Q.all来等待所有计算的完成,但是对于1000×1000来说,这样做可能不是一个好主意,尽pipe你可能会在内存中保留五十万个承诺。 根据你需要做的输出和原始数组的大小,可能或者可能不会更好地按顺序调用每个计算。 一种方法是使用recursion:

 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 AND y-> x来消除很多计算,这意味着循环可以for (j=i+1;j<pts.length;j++) ,我也用它我的代码在上面)

不pipe是不是更好地产生一个孩子的过程,我不知道,这可能是值得尝试的。