node.js - NodeJS : scanning a directory tree is slow as hell

标签 node.js performance node-webkit nw.js md5-file

我有一个 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();

最佳答案

使用任何 Node 模块,例如 https://github.com/jprichardson/node-klaw

Actually, I don't allocate anything!

不,您正在分配:任何对象创建或变量创建都会为此分配内存。此外,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();

打开任务管理器并在浏览器中运行此代码 - 您将看到内存消耗增长的速度。

关于node.js - NodeJS : scanning a directory tree is slow as hell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35769834/

相关文章:

angularjs - 我应该将 Angular 用于仅限本地的 NW.js 项目吗?

node.js - 需要 Electron 中 "client-side"JS 中的相对路径

javascript - node-webkit 从外部源运行函数

javascript - 在 JavaScript 中修改函数参数是一种不好的做法吗

performance - 为什么F#中的printf这么慢?

mysql - 从一个表中获取不在另一特定表中的所有 mysql 条目

c# - 任何快速检查两个 double 是否具有相同符号的方法?

linux - Linux 上的 node-webkit 和 WebGL

Node.js:如何路由网站 map

node.js - laravel5 的 yeoman 生成器 - composer create-project 的问题