我有一个节点应用程序,它在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秒。但是如果在前端镀铬,那就需要一秒钟(参见plunker)。当我在命令行上使用Node运行算法时,只需不到一秒钟。因此,我的应用程序在HTTP请求中运行算法的事实正在大幅减慢它的速度。所以有几个问题:
为什么会这样?为什么在HTTP请求中运行算法需要更长时间?
如果有的话,我该怎么做才能解决这个问题?是否有可能提出启动任务的请求,然后在完成后通知前端并检索PNG?
修改 我完全测试了运行算法并通过命令行创建PNG。它可以更快,不到半秒就可以计算出每个800k数据点应该是什么颜色。我想使用套接字向服务器发出请求并启动任务,然后让它返回图像。我很困惑,为什么代码在HTTP请求中运行时需要这么长时间......
修改 问题是Mongo和Mongoose。我将每个多边形的坐标存储在Mongo中。我获取这些坐标一次,但当我将它们与每个x,y点/进行比较时。不知何故,这是大大延迟算法的原因。如果我关闭Mongo文档,算法会从16秒到1.5秒......
修改 @DevDig指出了评论部分中的主要问题 - 当使用Mongoose对象时,有许多getter和setter减慢它的速度。在查询中使用lean()可将算法从16秒减少到1.5秒
答案 0 :(得分:2)
刚刚完成运行您的代码版本作为nodeJS服务。代码取自您的plunker。对于100,000行数据,执行时间为171毫秒(前10K行复制10次。这就是我所做的:
首先,你的data.json和gates.json文件不是真正的JSON文件,它们是javascript文件。我从前面删除了var data / gates =语句并删除了结尾的分号。您遇到的问题可能与您在应用中阅读数据集的方式有关。由于您不修改门或数据,因此我将其作为服务器设置的一部分进行读取,这正是您在浏览器中处理的方式。如果您每次访问服务器时都需要读取文件,那么当然会改变时间。这一改变使执行时间从171毫秒到515毫秒 - 仍然没有接近你所看到的。这是在macBook Pro上执行的。如果需要,我可以从网络访问的云服务器更新时间。
获取文件:
<%= truncate(this.thing, length: 15, separator: '...') %>
我移动了你的例程,将allGatesChain和事件创建到导出的函数中:
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 = 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]);
结果是171毫秒。