我有大约1000个需要解析的CSV文件。每个包含大约1000行,总共100万条记录。需要转换数据然后保存到数据库,这就是我必须通过我的应用程序执行此操作的原因。
我的问题是解析器在循环遍历文件时会逐渐变慢,直到完成运行需要它。
以下是目前的设置方式。
var files = [ file1Path, file2Path.... file1000Path ];
function parseFile(index) {
var startTime = new Date().getTime();
var filePath = files[index];
var stream = fs.createReadStream(filePath);
//parse using fast-csv npm module
csv.fromStream(stream, { config })
.on('data', function (row) {
transformAndSave(row);
})
.on('end', function () {
console.log( new Date().getTime() - startTime + " elapsed " );
parseFile(index + 1)
});
}
parseFile(0);
我尝试了几种不同的方式,每次都基本相同。第一个文件在2秒内完成,第8个文件在5秒或6秒完成,之后在上升到24秒等等。我尝试过的其他事情包括做... files.forEach(function (file) { //run the parser })
,做批次它一次只有100个,甚至一次只有5个,并没有区别:它逐渐从每秒500个速度减慢到每秒1个或2个。
有没有人知道如何防止这种减速?部分原因可能是stream.on('end')
在transformAndSave
完成之前完成,可能会产生积压。但是在这一点上,我没有想法,并且会感谢任何人都可以提供的任何帮助。
提前多多感谢!!
丹尼尔
对于流星人来说,请注意。我把这个函数称为Meteor方法。不确定这是否有所不同,但如果确实如此,现在你知道了。更新 这是日志输出,显示内存使用和处理时间的稳步上升。
答案 0 :(得分:2)
看起来像资源问题,就像你的内存不足一样。我会尝试一种不使用递归函数的方法,该函数可能允许更容易地释放资源。一种方法可能是使用async。
var Logger = require('arsenic-logger');
var fs = require('fs');
var async = require('async');
var csv = require('fast-csv');
var path = require('path');
Logger.echoMemoryUsage();
var testDir = path.resolve(__dirname, 'test');
fs.readdir(testDir, (err, files) => {
Logger.debug(files);
if (err) {
Logger.error(err);
}
async.mapLimit(files, 2, function(file, cb) {
var startTime = new Date().getTime();
var stream = fs.createReadStream(testDir+'/'+file);
Logger.debug("Reading: " + file);
config = {};
//parse using fast-csv npm module
csv.fromStream(stream, config)
.on('data', function(row) {
//Logger.debug(row);
//transformAndSave(row);
})
.on('error', function(err) {
Logger.error(err);
cb(err);
})
.on('end', function() {
Logger.debug(new Date().getTime() - startTime + " elapsed ");
setTimeout(cb, 1000);
});
}, function(err, results) {
Logger.info("Finished!");
process.exit(1);
});
});