我有一个NW.js应用程序,只需(递归)扫描目录树并获取每个文件/目录的统计信息。它还为文件执行MD5。
我有29k文件,850个文件夹,全部用于120GB数据。
差不多7分钟后,我的代码只在29k文件上扫描了4080个文件。
怎么可能这么慢?我能做些什么来提高性能吗?否则,Node对我来说没用......
令人惊讶的是,扫描1k文件只需“7秒”。为什么扫描文件只有4倍的时间长60倍?
当我检查进程时,我可以看到Node在RAM使用中移动了很多:从20MB到400MB(两种方式都有波动)。但CPU使用率停留在1%。
这很奇怪,因为我不认为我分配了这么多内存。实际上,我没有分配任何东西!请参阅下面的代码。
if (process.argv.length < 3)
process.exit();
var fs = require('fs');
var md5 = require('md5');
var md5File = require('md5-file');
var iTotal = 0;
var iNbFiles = 0;
var iNbFolders = 0;
var iBegin = Date.now();
var App =
{
scan: function(path)
{
var items = fs.readdirSync(path);
var i, item, stats, fullPath, isFolder, fileMD5;
var len = items.length;
var md5Hash = md5(path);
for (i = 0; i < len; i++)
{
item = items[i];
fullPath = path + '/' + item;
stats = fs.statSync(fullPath);
if (stats.isSymbolicLink())
continue;
isFolder = stats.isDirectory();
if (!isFolder)
{
fileMD5 = md5File(fullPath);
iNbFiles++;
}
else
{
fileMD5 = null;
iNbFolders++;
}
iTotal++;
process.send({_type: 'item', name: item, path: path, path_md5: md5Hash, full_path: fullPath, file_md5: fileMD5, stats: stats, is_folder: isFolder});
if (isFolder)
App.scan(path + '/' + item);
}
process.send({_type: 'temp', total: iTotal, files: iNbFiles, folders: iNbFolders, elapsed: (Date.now() - iBegin)});
}
};
App.scan(process.argv[2]);
// Send the final and definitive value of "total"
process.send({_type: 'total', total: iTotal, files: iNbFiles, folders: iNbFolders});
process.exit();
答案 0 :(得分:0)
使用https://github.com/jprichardson/node-fs-extra#walk
之类的任何节点模块实际上,我没有分配任何东西!
Nop,您正在分配:任何对象创建或变量创建都将为此分配内存。此外,md5文件通过流读取每个文件并计算校验和。因此,您需要将所有文件的所有内容发送到CPU和内存中。您使用MD5的同步版本 - 一次只能在文件上计算。 此外,你有递归,你有很多文件:这意味着,当堆栈结束时 - 你会有错误。而且我认为你有这个错误 - 你只是没有看到它,或者你没有任何进展反馈而无声地运行它。使用异步目录读取和异步MD5计算。最佳解决方案是使用一些工作流程集合(例如6个核心CPU - 6个工作者)并将数据提取给此工作人员,他们将计算MD5。
更新1
递归内存泄漏示例:
var i=0;
function inc() {
i++;
var s = ""
for(var n=0;n<4000;n++){ s+="0123456789" }
inc();
}
inc();
打开任务管理器并在浏览中运行此代码 - 您将看到内存消耗的增长速度。