我甚至不知道如何正确地提出这个问题,但我担心以下代码的性能(主要是内存消耗)。我预计这段代码会消耗大量内存,因为大型集合上的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)
});
}
答案 0 :(得分:1)
如果您担心在很短的时间内提交一百万个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个请求。但是如果你担心内存消耗,你仍然可以使用这种方法来避免用百万项填充内部队列。
答案 1 :(得分:1)
首先,我建议不要使用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是一种反模式,可能会导致代码在将来成为头疼的问题