我有一个节点应用程序,它可以在x,y点图上绘制数据。目前,我从前端发出GET请求,后端节点服务器接受请求,遍历数据点的数组,使用Node Canvas绘制画布,并将其流式传输到前端,在前端显示为PNG图像。
更复杂的是,可以有多边形,所以我的算法使用point in polygon包来计算点是否在多边形内部,如果是,则对数据点进行不同的颜色设置。
当数据点少于50,000个时,这种方法工作得很好。但是,当有800,000个请求时,请求大约需要23秒。我已经分析了代码,大部分时间都花在遍历所有数据点,并弄清楚在画布上绘制它的位置和颜色(取决于它是在一个还是多个多边形中)。这是我做的plunker。基本上我是这样做的:
for (var i = 0; i < data.length; i++) {
// get raw points
x = data[i][0];
y = data[i][1];
// convert to a point on canvas
pointX = getPointOnCanvas(x);
pointY = getPointOnCanvas(y, 'y');
color = getColorOfCell(pointX, pointY);
color = color;
plotColor.push({
color: color,
pointX: pointX,
pointY : pointY
});
}
// draw the dots down here算法本身不是问题所在。我遇到的问题是,当算法在HTTP请求中运行时,计算点的颜色需要很长时间-大约16秒。但如果在前端使用chrome,只需要一秒多一点的时间(参见柱塞)。当我使用Node在命令行上运行该算法时,所需时间不到一秒。因此,我的应用程序在HTTP请求中运行算法的事实大大减慢了它的速度。所以有几个问题:
为什么会这样呢?为什么在HTTP请求中运行算法需要这么长的时间?
我能做些什么来解决这个问题呢?有没有可能发出一个启动任务的请求,然后在任务完成时通知前端并检索PNG?
我对编辑PNG进行了全面测试,运行了算法,并通过命令行创建了。它要快得多,不到半秒就能计算出80万个数据点中的每个数据点应该是什么颜色。我正在考虑使用套接字向服务器发出请求并启动任务,然后让它返回图像。我很困惑,为什么代码在HTTP请求中运行时会花这么长时间……
编辑问题是和Mongoose。我将每个多边形的坐标存储在Mongo中。我获取这些坐标一次,但当我将它们与每个x,y点/进行比较时。不知何故,这就是大量延迟algoritm的原因。如果我关闭Mongo文档,算法从16秒到1.5秒......
Mongoose Edit @DevDig在评论部分指出了主要问题--当使用对象时,有很多getter和setter会减慢它的速度。在查询中使用lean()可以将算法从16秒减少到1.5秒
发布于 2017-06-09 22:18:44
刚刚将代码的一个版本作为nodeJS服务运行完毕。代码是从你的柱塞上取出来的。100,000行数据的执行时间为171mSec (复制前10K行10次。下面是我所做的:
首先,你的data.json和gates.json文件并不是JSON文件,它们是javascript文件。我从前面删除了var data/gate=语句,并删除了结尾的分号。您遇到的问题可能与您在应用程序中读取数据集的方式有关。由于您不修改gates或数据,因此我将它们作为服务器上设置的一部分读取,这正是您在浏览器中进行处理的方式。如果您需要在每次访问服务器时读取文件,那么,当然,这会改变时间。这一改变花费了执行时间从171mSec到515mSec -仍然没有接近你所看到的。这是在macBook专业版上执行的。如果需要,我可以从网络访问的云服务器更新时间。
获取文件:
var fs = require("fs");
var path = require("path");
var data = [];
var allGatesChain;
var events = [];
var x, y, pointX, pointY;
var filename = __dirname + "/data.txt";
data = JSON.parse(fs.readFileSync(filename, "utf-8"));
filename = __dirname + "/gates.json";
var gates = JSON.parse(fs.readFileSync(filename, "utf-8"));我将创建allGatesChain和事件的例程移到了导出函数中:
allGatesChain = getAllGatesChain();
generateData();
console.log("events is "+events.length+" elements long. events[0] is: "+events[0]);
console.log("data is "+data.length+" elements long. data[0] is "+data[0]);然后运行你的代码:
var start, end;
var plotColor = [];
start = new Date().getTime();
for (var i = 0; i < data.length; i++) {
// get raw points
x = data[i][0];
y = data[i][1];
// convert to a point on canvas
pointX = getPointOnCanvas(x);
pointY = getPointOnCanvas(y, 'y');
color = getColorOfCell({
gateChain: allGatesChain,
events: events,
i: i
});
color = color;
plotColor.push({
color: color,
pointX: pointX,
pointY : pointY
});
}
end = new Date().getTime();
var _str = "loop execution took: "+(end-start)+" milliseconds.";
console.log(_str);
res.send(_str);结果为171mSec。
https://stackoverflow.com/questions/44329485
复制相似问题