0

Node.jsを使用して大きなファイルを1行ずつ処理したいと思います。サイズは100MB、行数は500,000です。入力ファイルの行を読み取るためのこのソリューションを見つけました

javascript --node.js:テキストファイルを配列に読み込みます。(各行は配列内のアイテムです。)-スタックオーバーフロー

これで、各行を新しい出力ファイルに書き込むことができるので、試してみます

function readLines(input, func)
{
    var remaining = "";

    input.on("data", function(data)
    {
        remaining += data;
        var index = remaining.indexOf("\n");
        var last = 0;
        while (index > -1)
        {
            var line = remaining.substring(last, index);
            last = index + 1;
            func(line);
            index = remaining.indexOf("\n", last);
        }

        remaining = remaining.substring(last);
    });

    input.on("end", function()
    {
        if (remaining.length > 0)
        {
            func(remaining);
        }
    });
}

function write(data)
{
    var written = output.write(data);
}

var fs = require("fs");
var input = fs.createReadStream("input.txt");
var output = fs.createWriteStream("output.txt", {flags: "w"});
readLines(input, write);

ただし、スクリプトは非常に遅く、入力ファイルを完全に処理するのに1時間以上かかり、CPUとRAMの使用量が多くなります(CPUの量は25、メモリの使用量は最大200MBです)。それで、それを最適化する方法があるかどうか誰かに教えてもらえますか?

4

1 に答える 1

1

あなたが直面している問題は、常に 1) 文字列に追加し、2) 文字列をスライスしていることです。これらの操作は両方とも、新しい文字列が割り当てられ、古いデータがコピーされる可能性があります。これは低速です。古い文字列は参照されなくなったため、最終的にガベージ コレクションによって解放されますが、これには時間がかかるため、大量のメモリが使用されます。

もちろん、これを行うにはもっと簡単な方法がありますが、Node.JS のストリームを使用してそれを行う方法を学びたいと思っていると思います。この種の状況で多数のアペンドとスライスを置き換えるために使用できる一般的な手法は、文字列の配列にデータを蓄積することです。後で文字列の配列を単一の配列に結合して、 にmystring.join("")変換でき["hello, ", "world"]ます"hello, world"。文字列の配列を作成してからそれらを一度に結合して大きな文字列にする方が、各文字列を最後に追加して文字列を作成するよりもはるかに高速です。

この問題を解決し、そこから何かを学ぶのに役立ち、十分であることを願っています!

于 2013-03-03T07:31:29.320 に答える