Mar*_*ark 16 javascript algorithm mongoose mongodb node.js
我有一个节点应用程序,它在x,y点图表上绘制数据.目前,我从前端发出GET请求,我的后端节点服务器接受请求,循环遍历数据点数组,使用Node Canvas绘制画布并将其流回到前端,在那里它显示为PNG图像.
使事情变得复杂的是,可以存在多边形,因此我的算法使用多边形包中的点来计算点是否在多边形内部,并且如果数据指向的话,那么数据的颜色会不同.
当数据点少于50,000时,此工作正常.但是,当有800,000时,请求大约需要23秒.我已经对代码进行了分析,大部分时间用于遍历所有数据点,并确定在画布上绘制的位置以及颜色(取决于它是否在一个或多个多边形中).这是我制作的一个傻瓜.基本上我做这样的事情:
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
Run Code Online (Sandbox Code Playgroud)
算法本身不是问题.我遇到的问题是,当算法在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秒
刚刚完成将代码版本作为 NodeJS 服务运行。该代码是从你的骗子那里获取的。对于 100,000 行数据,执行时间为 171 毫秒(将前 10K 行复制 10 次。这是我所做的:
首先,您的 data.json 和 Gates.json 文件并不是真正的 JSON 文件,它们是 javascript 文件。我从前面删除了 var data/gates = 语句,并删除了结尾的分号。您遇到的问题可能与您在应用程序中读取数据集的方式有关。由于您不修改门或数据,因此我将它们作为服务器上设置的一部分读取,这正是您在浏览器中处理的方式。如果您每次访问服务器时都需要读取文件,那么当然会改变时间。这一更改将执行时间从 171 毫秒缩短到 515 毫秒 - 仍然与您所看到的相差甚远。这是在 MacBook Pro 上执行的。如果需要,我可以从网络访问的云服务器更新计时。
获取文件:
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"));
Run Code Online (Sandbox Code Playgroud)
我将创建 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]);
Run Code Online (Sandbox Code Playgroud)
然后运行你的代码:
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);
Run Code Online (Sandbox Code Playgroud)
结果是 171 毫秒。
| 归档时间: |
|
| 查看次数: |
327 次 |
| 最近记录: |