我甚至不知道如何恰当地问这个问题,但我担心以下代码的性能(主要是内存消耗)。我预计这段代码将消耗大量内存,因为大量的map和许多等待外部服务的“挂起”函数。我的担忧在这里是合理的吗?什么是更好的方法?
var list = fs.readFileSync('./mailinglist.txt') // say 1.000.000 records
.split("\n")
.map( processEntry );
var processEntry = function _processEntry(i){
i = i.split('\t');
getEmailBody( function(emailBody, name){
var msg = {
"message" : emailBody,
"name" : i[0]
}
request(msg, function reqCb(err, result){
...
});
}); // getEmailBody
}
var getEmailBody = function _getEmailBody(obj, cb){
// read email template from file;
// v() returns the correct form for person's name with web-based service
v(obj.name, function(v){
cb(obj, v)
});
}发布于 2014-09-16 20:37:26
如果您担心在很短的时间内提交一百万个http请求(您可能应该这样做),那么您必须设置某种类型的缓冲区。
一个简单的方法就是:
var lines = fs.readFileSync('./mailinglist.txt').split("\n");
var entryIdx = 0;
var done = false;
var processNextEntry = function () {
if (entryIdx < lines.length) {
processEntry(lines[entryIdx++]);
} else {
done = true;
}
};
var processEntry = function _processEntry(i){
i = i.split('\t');
getEmailBody( function(emailBody, name){
var msg = {
"message" : emailBody,
"name" : name
}
request(msg, function reqCb(err, result){
// ...
!done && processNextEntry();
});
}); // getEmailBody
}
// getEmailBody didn't change
// you set the ball rolling by calling processNextEntry n times,
// where n is a sensible number of http requests to have pending at once.
for (var i=0; i<10; i++) processNextEntry();编辑:根据this blog post节点有一个内部队列系统,它将只允许5个同时请求。但是,如果您担心内存消耗,您仍然可以使用此方法来避免用一百万个项目来填满内部队列。
发布于 2014-09-16 21:33:22
首先,我建议不要使用readFileSync,相反,我倾向于使用异步等效项。应该避免阻塞IO操作,因为从磁盘读取是非常昂贵的,虽然这是您现在代码的唯一目的,但我会考虑这种情况在未来可能会发生什么变化-随意浪费时钟周期从来都不是一个好主意。
对于大型数据文件,我会在定义的块中读取它们,并对其进行处理。如果您能想出一些模式,无论是用来区分文件中的数据块的标记,还是填充边界,然后逐段地处理文件。
这很粗糙,在我脑海中没有经过测试,但大概是这样的:
var fs = require("fs");
function doMyCoolWork(startByteIndex, endByteIndex){
fs.open("path to your text file", 'r', function(status, fd) {
var chunkSize = endByteIndex - startByteIndex;
var buffer = new Buffer(chunkSize);
fs.read(fd, buffer, 0, chunkSize, 0, function(err, byteCount) {
var data = buffer.toString('utf-8', 0, byteCount);
// process your data here
if(stillWorkToDo){
//recurse
doMyCoolWork(endByteIndex, endByteIndex + 100);
}
});
});
}或者查看流程库函数中的一个,以获得类似的功能。
H2H
ps。Javascript和Node与异步和事件一起工作得非常好。在我看来,使用sync是一种反模式,并且很可能导致代码在未来成为一个令人头疼的问题。
https://stackoverflow.com/questions/25868015
复制相似问题