【发布时间】:2015-07-17 15:29:18
【问题描述】:
我有一个 10 GB 特定格式的日志文件,我想逐行处理此文件,然后将输出写入其他文件 应用了一些转换。我正在使用节点进行此操作。
虽然这种方法很好,但要花很多时间才能做到这一点。我能够在 JAVA 中在 30-45 分钟内完成此操作,但在节点中完成相同的工作需要 160 多分钟。以下是代码:
以下是从输入中读取每一行的启动代码。
var path = '../10GB_input_file.txt';
var output_file = '../output.txt';
function fileopsmain(){
fs.exists(output_file, function(exists){
if(exists) {
fs.unlink(output_file, function (err) {
if (err) throw err;
console.log('successfully deleted ' + output_file);
});
}
});
new lazy(fs.createReadStream(path, {bufferSize: 128 * 4096}))
.lines
.forEach(function(line){
var line_arr = line.toString().split(';');
perform_line_ops(line_arr, line_arr[6], line_arr[7], line_arr[10]);
}
);
}
这是对该行执行某些操作的方法,并且 将输入传递给 write 方法以将其写入输出文件。
function perform_line_ops(line_arr, range_start, range_end, daynums){
var _new_lines = '';
for(var i=0; i<days; i++){
//perform some operation to modify line pass it to print
}
write_line_ops(_new_lines);
}
以下方法用于将数据写入新文件。
function write_line_ops(line) {
if(line != null && line != ''){
fs.appendFileSync(output_file, line);
}
}
我想把这个时间缩短到 15-20 分钟。有没有可能这样做。
另外,我正在使用 8 GB RAM 的英特尔 i7 处理器 上尝试此操作。
【问题讨论】:
-
一个有效的问题是
lazy模块是否在处理之前将整个文件读入内存而不是逐行流式传输?您可能会对node-byline 模块感兴趣。 -
如果我正在处理这个问题,第一步是在一个小得多的文件上对每一步进行计时,看看究竟是什么导致了速度变慢。从那里,您可以开始优化这部分代码。
-
@jfriend00 没有延迟模块不会将整个文件加载到内存中,因为我正在同时监控内存使用情况。
-
@Kevin B 我正在做同样的事情,我正在处理一个 400MB 的文件,该文件在大约 2.5 分钟内得到处理。虽然我不确定是什么导致了这里的问题。
-
我建议你先把问题绑定到这里。创建一个简单的测试应用程序,它只创建一个读取流并读取整个文件,而无需担心行数和写入磁盘。看看这需要多长时间。如果这很快,那么您可以一次将一块拼图添加到拼图中,并随时跟踪您的进度。接下来将管道添加到新文件名并查看性能。如果原始读取速度很慢,那么问题在 nodejs 流中较低,您将不得不降低级别来修复性能。
标签: node.js file-io large-files file-handling file-processing