3

ディレクトリツリーを単純に(再帰的に)スキャンし、各ファイル/ディレクトリの統計を取得するNW.jsアプリがあります。また、ファイルの MD5 も実行します。

29,000 個のファイル、850 個のフォルダーがあり、すべて 120GB のデータ用です。

ほぼ 7 分後、私のコードは 29,000 個のファイルのうち 4,080 個のファイルしかスキャンしませんでした。

こんなに遅いのはどうしてですか??パフォーマンスを向上させるためにできることはありますか? そうでなければ、ノードは役に立たないでしょう...

驚くべきことは、1,000 個のファイルをスキャンするのに「わずか」7 秒しかかからなかったことです。わずか 4 倍のファイルをスキャンするのに 60 倍の時間がかかるのはなぜですか?

プロセスを確認すると、Node の RAM 使用量が 20MB から 400MB に大きく変化していることがわかります (両方向に変動します)。しかし、CPU 使用率は 1% のままです。

それほど多くのRAMを割り当てているとは思わないので、奇妙です。実際、私は何も割り当てません!以下の私のコードを見てください。

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();
4

1 に答える 1

0

https://github.com/jprichardson/node-fs-extra#walkのような任意のノード モジュールを使用します

実際、私は何も割り当てません!

いいえ、割り当てています。オブジェクトの作成または変数の作成により、これにメモリが割り当てられます。また、md5-file はストリーム経由で各ファイルを読み取り、チェックサムを計算します。したがって、すべてのファイルのすべてのコンテンツを送信して、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();

タスク マネージャーを開き、ブラウズでこのコードを実行すると、メモリ消費がどれだけ速く増加するかがわかります。

于 2016-03-04T09:00:52.707 に答える