数百个坐标之间的Nodejs距离计算阻塞了我的服务器
Posted
技术标签:
【中文标题】数百个坐标之间的Nodejs距离计算阻塞了我的服务器【英文标题】:Nodejs distance calculation between hundreds of coordinates is blocking my server 【发布时间】:2015-08-20 08:39:06 【问题描述】:我有数百个坐标(纬度、经度)的列表。 对于每个客户请求,我需要计算每对这些点之间的距离。 对于 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;
【问题讨论】:
你应该看看 process.nextTick() 函数。我不确定它能否解决您的问题,但这是我将尝试的第一首曲目。 它仍然会阻塞服务器 500 毫秒,无论哪种方式.. 它只会将阻塞延迟到下一个滴答声.. 没有额外的、专门的 nodejs 服务器来完成这个任务,这是一个更好的选择? 如果您将代码重构为每处理 100 或 500 距离执行 process.nextTick,则不会。 不错的方法。所以我假设每处理 100 个距离后,节点的 process.nextTick 将使节点可用于其他请求,因此只会在计算 100 个距离所需的一小段时间内被阻塞。我会尝试的。但是仍然-在单独的小型nodejs本地网络服务器中进行此计算距离不是更简单(更快)吗?两个nodejs进程之间没有共享资源,所以我看不到它有任何问题 【参考方案1】:这在一定程度上取决于您需要对结果做什么。您是否需要一系列距离作为输出?
一种方法是使用诸如 Q 之类的 Promise 将每个计算变成一个单独的操作,然后使用 Q.all
等待所有计算完成,但是对于 1000x1000 这样做可能不是一个好主意,因为您将不得不在内存中保留一个包含 50 万个承诺的数组。根据您需要对输出执行的操作以及原始点数组的大小,按顺序调用每个计算可能会更好,也可能不会更好。一种方法是使用递归:
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++)
,我在上面的代码中也使用了它)
生成一个我不知道的子进程是否更好,这可能值得一试。
【讨论】:
以上是关于数百个坐标之间的Nodejs距离计算阻塞了我的服务器的主要内容,如果未能解决你的问题,请参考以下文章